From dead85f8d5aa2445b1de723979b78d973a522310 Mon Sep 17 00:00:00 2001 From: Timo Dritschler Date: Fri, 25 Jul 2014 11:32:55 +0200 Subject: Added 'kiro_server_stop' method to KIRO Server Added missing cleanup to kiro_server_finalize Added missing cleanup to test-server --- src/kiro-server.c | 88 +++++++++++++++++++++++++++++++++++++----------------- src/kiro-server.h | 14 +++++++-- test/test-server.c | 2 ++ 3 files changed, 75 insertions(+), 29 deletions(-) diff --git a/src/kiro-server.c b/src/kiro-server.c index 276388b..9a76007 100644 --- a/src/kiro-server.c +++ b/src/kiro-server.c @@ -50,13 +50,14 @@ struct _KiroServerPrivate { /* 'Real' private structures */ /* (Not accessible by properties) */ - struct rdma_event_channel *ec; // Main Event Channel - struct rdma_cm_id *base; // Base-Listening-Connection - struct kiro_connection *client; // Connection to the client - pthread_t event_listener; // Pointer to the completion-listener thread of this connection - pthread_mutex_t mtx; // Mutex to signal the listener-thread termination - void *mem; // Pointer to the server buffer - size_t mem_size; // Server Buffer Size in bytes + struct rdma_event_channel *ec; // Main Event Channel + struct rdma_cm_id *base; // Base-Listening-Connection + struct kiro_connection *client; // Connection to the client + pthread_t event_listener; // Pointer to the completion-listener thread of this connection + pthread_mutex_t mtx; // Mutex to signal the listener-thread termination + int close_signal; // Integer flag used to signal to the listener-thread that the server is going to shut down + void *mem; // Pointer to the server buffer + size_t mem_size; // Server Buffer Size in bytes }; @@ -75,9 +76,9 @@ static void kiro_server_finalize (GObject *object) { KiroServer *self = KIRO_SERVER(object); - KiroServerPrivate *priv = KIRO_SERVER_GET_PRIVATE(self); - pthread_mutex_unlock(&(priv->mtx)); - pthread_join(priv->event_listener, NULL); + + //Clean up the server + kiro_server_stop(self); } @@ -201,11 +202,14 @@ void * event_loop (void *self) KiroServerPrivate *priv = KIRO_SERVER_GET_PRIVATE((KiroServer *)self); struct rdma_cm_event *active_event; - int stop = 0; - - while(0 == stop) { + while(0 == priv->close_signal) { if(0 <= rdma_get_cm_event(priv->ec, &active_event)) { + //Lock mutex to signal that this thread is currently handling an event + //and disable cancellation to prevent undefined states during shutdown + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + pthread_mutex_lock(&(priv->mtx)); + struct rdma_cm_event *ev = malloc(sizeof(*active_event)); if(!ev) @@ -219,7 +223,15 @@ void * event_loop (void *self) if (ev->event == RDMA_CM_EVENT_CONNECT_REQUEST) { - + + if (0 != priv->close_signal) + { + //Main thread has signalled shutdown! + //Don't connect this client any more + //Sorry mate! + rdma_reject(ev->id, NULL, 0); + } + /* priv->client = (struct kiro_connection *)calloc(1, sizeof(struct kiro_connection)); if(!(priv->client)) @@ -242,16 +254,14 @@ void * event_loop (void *self) else if(ev->event == RDMA_CM_EVENT_DISCONNECTED) { printf("Got disconnect request.\n"); - //pthread_mutex_unlock(&(priv->mtx)); kiro_destroy_connection(&(ev->id)); printf("Connection closed successfully\n"); } free(ev); } - // Mutex will be freed as a signal to stop request - if(0 == pthread_mutex_trylock(&(priv->mtx))) - stop = 1; + pthread_mutex_unlock(&(priv->mtx)); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); } printf("Closing Event Listener Thread\n"); @@ -332,14 +342,7 @@ int kiro_server_start (KiroServer *self, char *address, char *port, void* mem, s priv->mem = mem; priv->mem_size = mem_size; - priv->ec = rdma_create_event_channel(); - int oldflags = fcntl (priv->ec->fd, F_GETFL, 0); - /* Only change the FD Mode if we were able to get its flags */ - if (oldflags >= 0) { - oldflags |= O_NONBLOCK; - /* Store modified flag word in the descriptor. */ - fcntl (priv->ec->fd, F_SETFL, oldflags); - } + priv->ec = rdma_create_event_channel(); if(rdma_migrate_id(priv->base, priv->ec)) { printf("Was unable to migrate connection to new Event Channel.\n"); @@ -348,7 +351,6 @@ int kiro_server_start (KiroServer *self, char *address, char *port, void* mem, s } pthread_mutex_init(&(priv->mtx), NULL); - pthread_mutex_lock(&(priv->mtx)); pthread_create(&(priv->event_listener), NULL, event_loop, self); printf("Enpoint listening.\n"); @@ -358,6 +360,38 @@ int kiro_server_start (KiroServer *self, char *address, char *port, void* mem, s } +void +kiro_server_stop (KiroServer *self) +{ + if(!self) + return; + + KiroServerPrivate *priv = KIRO_SERVER_GET_PRIVATE (self); + + if(!priv->base) + return; + + //Shut down the listener-thread + priv->close_signal = 1; + pthread_mutex_lock(&(priv->mtx)); + pthread_cancel(priv->event_listener); + pthread_join(priv->event_listener, NULL); + printf("Event Listener Thread stopped.\n"); + priv->close_signal = 0; + + /* + * FOR ALL PRIV->CLIENT : DISCONNECT + */ + + rdma_destroy_ep(priv->base); + priv->base = NULL; + rdma_destroy_event_channel(priv->ec); + priv->ec = NULL; + + printf("Server stopped successfully.\n"); +} + + diff --git a/src/kiro-server.h b/src/kiro-server.h index cb9b57c..ea853c3 100644 --- a/src/kiro-server.h +++ b/src/kiro-server.h @@ -78,13 +78,13 @@ GObject kiro_server_new (void); /** * kiro_server_start - Starts the server, providing the given memory - * @server: KIRO SERVER to perform the operation on + * @server: #KiroServer to perform the operation on * @bind_addr: Local address to bind the server to * @bind_port: Local port to listen for connections * @mem: Pointer to the memory that is to be provided * @mem_size: Size in bytes of the given memory * Description: - * Starts the server to provide the given memory to any connecting + * Starts the #KiroServer to provide the given memory to any connecting * client. * Notes: * If the bind_addr is NULL, the server will bind to the first device @@ -101,6 +101,16 @@ GObject kiro_server_new (void); */ int kiro_server_start (KiroServer* server, char* bind_addr, char* bind_port, void* mem, size_t mem_size); +/** + * kiro_server_stop - Stops the server + * @server: #KiroServer to perform the operation on + * Description: + * Stops the given #KiroServer + * See also: + * kiro_server_start + */ +void kiro_server_stop (KiroServer* server); + G_END_DECLS #endif //__KIRO_SERVER_H \ No newline at end of file diff --git a/test/test-server.c b/test/test-server.c index 63fefaa..7755015 100644 --- a/test/test-server.c +++ b/test/test-server.c @@ -160,9 +160,11 @@ int main(void) frame++; } + done: g_rand_free(rand); g_object_unref(rb); + g_object_unref(server); return 0; } \ No newline at end of file -- cgit v1.2.3