Skip to content
Snippets Groups Projects
Commit 7e83b7f9 authored by Marek Vavrusa's avatar Marek Vavrusa
Browse files

Intercepting SIGINT for clean exit.

parent ceb8446f
No related branches found
No related tags found
No related merge requests found
#include <stdio.h>
#include <signal.h>
#include "common.h"
#include "server.h"
......@@ -7,6 +8,17 @@
/*----------------------------------------------------------------------------*/
static cute_server* server_singleton = NULL;
// SIGINT signal handler
void interrupt_handle(int s)
{
// Stop server
if(s == SIGINT && server_singleton != NULL) {
cute_stop(server_singleton);
}
}
int main( int argc, char **argv )
{
if (argc < 2) {
......@@ -17,7 +29,7 @@ int main( int argc, char **argv )
// Open log
log_open(LOG_UPTO(LOG_ERR), LOG_MASK(LOG_ERR)|LOG_MASK(LOG_WARNING));
int res;
int res = 0;
// res = test_skip_list();
// if (res != 0) {
......@@ -25,15 +37,26 @@ int main( int argc, char **argv )
// }
// Start server
cute_server *server = cute_create();
// Create server instance
cute_server* server = cute_create();
// Register service and signal handler
server_singleton = server;
struct sigaction sa;
sa.sa_handler = interrupt_handle;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
// Run server
if ((res = cute_start(server, argv[1])) != 0) {
log_error("Problem starting the server, exiting..\n");
}
// Stop server and close log
cute_destroy(&server);
cute_destroy(&server);
log_close();
return res;
return res;
}
......@@ -8,7 +8,6 @@
/*----------------------------------------------------------------------------*/
static const int DEFAULT_THR_COUNT = 2;
static const unsigned short DEFAULT_PORT = 53535;
/*----------------------------------------------------------------------------*/
......@@ -60,8 +59,9 @@ cute_server *cute_create()
debug_server("Done\n\n");
debug_server("Creating Dispatcher structure..\n");
// Create master dispatchers
for(int i = 0; i < 2; i++) {
server->dispatcher[i] = dpt_create(DEFAULT_THR_COUNT, &sm_listen, server->manager[i]);
server->dispatcher[i] = dpt_create(1, &sm_listen, server->manager[i]);
if (server->dispatcher[i] == NULL) {
sm_destroy(&server->manager[UDP]);
sm_destroy(&server->manager[TCP]);
......@@ -87,41 +87,65 @@ int cute_start( cute_server *server, const char *filename )
}
debug_server("Opening sockets..\n");
server->manager[UDP]->is_running = 1;
if (sm_open_socket(server->manager[UDP], DEFAULT_PORT, UDP) != 0) {
printf("[failed]\n");
perror("sm_open_socket");
return -1;
}
#ifdef CUTE_DEBUG
printf("TCP(%d) ", DEFAULT_PORT); fflush(stdout);
#endif
server->manager[TCP]->is_running = 1;
if (sm_open_socket(server->manager[TCP], DEFAULT_PORT, TCP) != 0) {
#ifdef CUTE_DEBUG
printf("[failed]\n");
#endif
perror("sm_open_socket");
return -1;
}
#ifdef CUTE_DEBUG
printf("\nDone\n\n");
#endif
debug_server("Starting the Dispatcher..\n");
// Start dispatchers
int ret = 0;
ret = dpt_start(server->dispatcher[TCP]);
#ifdef CUTE_DEBUG
printf(" TCP handler: %u threads started.\n", server->dispatcher[TCP]->thread_count);
#endif
ret += dpt_start(server->dispatcher[UDP]);
#ifdef CUTE_DEBUG
printf(" UDP handler: %u threads started.\n", server->dispatcher[UDP]->thread_count);
#endif
if(ret < 0)
return ret;
// Wait for dispatchers to finish
/// \todo Intercept SIGINT for clean exit.
ret = dpt_wait(server->dispatcher[TCP]);
#ifdef CUTE_DEBUG
printf("TCP handler finished.\n");
#endif
ret += dpt_wait(server->dispatcher[UDP]);
#ifdef CUTE_DEBUG
printf("UDP handler finished.\n");
#endif
return ret;
}
/*----------------------------------------------------------------------------*/
void cute_stop( cute_server *server )
{
// Notify servers to stop
for(int i = 0; i < 2; i++) {
sm_stop(server->manager[i]);
}
}
/*----------------------------------------------------------------------------*/
void cute_destroy( cute_server **server )
{
dpt_destroy(&(*server)->dispatcher[UDP]);
......
......@@ -59,6 +59,11 @@ cute_server *cute_create();
*/
int cute_start( cute_server *server, const char *filename );
/*!
* @brief Requests server to stop.
*/
void cute_stop( cute_server *server );
/*!
* @brief Properly destroys the server structure.
*/
......
......@@ -15,8 +15,11 @@
#include <unistd.h>
#include <assert.h>
const uint SOCKET_BUFF_SIZE = 4096;
//#define SM_DEBUG
const uint SOCKET_BUFF_SIZE = 4096; /// \todo <= MTU size
const uint DEFAULT_EVENTS_COUNT = 1;
static const int DEFAULT_THR_COUNT = 2;
/*----------------------------------------------------------------------------*/
/* Non-API functions */
......@@ -472,19 +475,24 @@ void *sm_listen( void *obj )
return NULL;
}
while (1) {
while (manager->is_running) {
/// \bug What if events count changes in another thread and backing
/// store gets reallocated? Memory error in loop reading probably.
// Reserve 2x backing-store size
sm_reserve_events(manager, manager->events_count * 2);
int nfds = epoll_wait(manager->epfd, manager->events,
manager->events_count, -1);
manager->events_count, 1000);
if (nfds < 0) {
printf("ERROR: %d: %s.\n", errno, strerror(errno));
return NULL;
}
// Signalized finish
if(!manager->is_running) {
break;
}
// for each ready socket
for(int i = 0; i < nfds; i++) {
//printf("locking mutex from thread %ld\n", pthread_self());
......@@ -494,4 +502,11 @@ void *sm_listen( void *obj )
}
}
return NULL;
}
void sm_stop( sm_manager *manager )
{
manager->is_running = 0;
close(manager->epfd);
}
......@@ -47,7 +47,6 @@ typedef void (*iohandler_t) (sm_event*);
typedef struct sm_manager {
sm_socket *sockets;
// int socket_count;
struct epoll_event *events;
int events_count;
int events_max;
......@@ -55,6 +54,7 @@ typedef struct sm_manager {
pthread_mutex_t mutex;
ns_nameserver *nameserver;
iohandler_t handler;
volatile int is_running;
} sm_manager;
/*----------------------------------------------------------------------------*/
......@@ -65,6 +65,7 @@ sm_manager *sm_create( ns_nameserver *nameserver );
int sm_open_socket( sm_manager *manager, unsigned short port, socket_t type);
int sm_close_socket( sm_manager *manager, unsigned short port);
void *sm_listen( void *obj );
void sm_stop( sm_manager *manager );
void sm_destroy( sm_manager **manager );
// Handlers
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment