Commit 7e83b7f9 authored by Marek Vavrusa's avatar Marek Vavrusa

Intercepting SIGINT for clean exit.

parent ceb8446f
#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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment