Index: lib/gam_error.c =================================================================== RCS file: /cvs/gnome/gamin/lib/gam_error.c,v retrieving revision 1.11 diff -u -p -r1.11 gam_error.c --- lib/gam_error.c 19 Apr 2006 08:28:14 -0000 1.11 +++ lib/gam_error.c 5 Sep 2006 14:02:43 -0000 @@ -18,6 +18,7 @@ typedef void (*signal_handler) (int); extern void gam_show_debug(void); +extern void gam_got_signal (void); int gam_debug_active = 0; static int initialized = 0; @@ -60,11 +61,13 @@ gam_error_handle_signal(void) } } + static void gam_error_signal(int no) { got_signal = !got_signal; gam_debug_active = -1; /* force going into gam_debug() */ + gam_got_signal (); } /** Index: libgamin/gam_api.c =================================================================== RCS file: /cvs/gnome/gamin/libgamin/gam_api.c,v retrieving revision 1.40 diff -u -p -r1.40 gam_api.c --- libgamin/gam_api.c 16 Aug 2006 15:42:44 -0000 1.40 +++ libgamin/gam_api.c 5 Sep 2006 14:02:43 -0000 @@ -87,6 +87,13 @@ void gam_show_debug(void) { } +void gam_got_signal(void); + +void +gam_got_signal(void) { +} + + /************************************************************************ * * * Path for the socket connection * Index: server/gam_connection.c =================================================================== RCS file: /cvs/gnome/gamin/server/gam_connection.c,v retrieving revision 1.29 diff -u -p -r1.29 gam_connection.c --- server/gam_connection.c 22 Sep 2005 08:09:03 -0000 1.29 +++ server/gam_connection.c 5 Sep 2006 14:02:43 -0000 @@ -42,6 +42,9 @@ struct GamConnData { guint eq_source; /* the event queue GSource id */ }; +static void gam_cancel_server_timeout (void); + + static const char * gam_reqtype_to_string (GAMReqType type) { @@ -126,6 +129,9 @@ gam_connection_close(GamConnDataPtr conn g_free(conn->pidname); g_free(conn); + if (gamConnList == NULL && gam_server_use_timeout ()) + gam_schedule_server_timeout (); + return (0); } @@ -196,6 +202,8 @@ gam_connection_new(GMainLoop *loop, GIOC ret->eq_source = g_timeout_add (100 /* ms */, gam_connection_eq_flush, ret); gamConnList = g_list_prepend(gamConnList, ret); + gam_cancel_server_timeout (); + GAM_DEBUG(DEBUG_INFO, "Created connection %d\n", ret->fd); return (ret); @@ -683,7 +691,9 @@ gam_send_ack(GamConnDataPtr conn, int re * * ************************************************************************/ -#define MAX_IDLE_TIMEOUT 30 +#define MAX_IDLE_TIMEOUT_MSEC (30*1000) /* 30 seconds */ + +static guint server_timeout_id = 0; /** * gam_connections_check: @@ -692,27 +702,33 @@ gam_send_ack(GamConnDataPtr conn, int re * shuts the server down if there have been no outstanding connections * for a while. */ -gboolean +static gboolean gam_connections_check(void) { - static time_t timeout; - - if (g_list_first(gamConnList) != NULL) { - if (timeout != 0) { - GAM_DEBUG(DEBUG_INFO, "New active connection\n"); - } - timeout = 0; - return (TRUE); - } - if (timeout == 0) { - GAM_DEBUG(DEBUG_INFO, "No more active connections\n"); - timeout = time(NULL); - } else if (time(NULL) - timeout > MAX_IDLE_TIMEOUT) { + server_timeout_id = 0; + + if (gamConnList == NULL) { GAM_DEBUG(DEBUG_INFO, "Exiting on timeout\n"); gam_shutdown(); exit(0); } - return (TRUE); + return (FALSE); +} + +static void +gam_cancel_server_timeout (void) +{ + if (server_timeout_id) + g_source_remove (server_timeout_id); + server_timeout_id = 0; +} + +void +gam_schedule_server_timeout (void) +{ + gam_cancel_server_timeout (); + server_timeout_id = + g_timeout_add(MAX_IDLE_TIMEOUT_MSEC, (GSourceFunc) gam_connections_check, NULL); } /** Index: server/gam_connection.h =================================================================== RCS file: /cvs/gnome/gamin/server/gam_connection.h,v retrieving revision 1.6 diff -u -p -r1.6 gam_connection.h --- server/gam_connection.h 4 Aug 2005 16:45:25 -0000 1.6 +++ server/gam_connection.h 5 Sep 2006 14:02:43 -0000 @@ -25,7 +25,7 @@ typedef enum { int gam_connections_init (void); int gam_connections_close (void); -gboolean gam_connections_check (void); +void gam_schedule_server_timeout (void); GamConnDataPtr gam_connection_new (GMainLoop *loop, GIOChannel *source); Index: server/gam_server.c =================================================================== RCS file: /cvs/gnome/gamin/server/gam_server.c,v retrieving revision 1.42 diff -u -p -r1.42 gam_server.c --- server/gam_server.c 8 Sep 2005 10:12:03 -0000 1.42 +++ server/gam_server.c 5 Sep 2006 14:02:44 -0000 @@ -279,6 +279,17 @@ static GHashTable *listeners = NULL; static GIOChannel *socket = NULL; /** + * gam_server_use_timeout: + * + * Returns TRUE if idle server should exit after a timeout. + */ +gboolean +gam_server_use_timeout (void) +{ + return !no_timeout; +} + +/** * gam_server_emit_one_event: * @path: the file/directory path * @event: the event type @@ -507,6 +519,58 @@ gam_poll_file (GamNode *node) return 0; } +#ifdef GAM_DEBUG_ENABLED + +static GIOChannel *pipe_read_ioc = NULL; +static GIOChannel *pipe_write_ioc = NULL; + +static gboolean +gam_error_signal_pipe_handler(gpointer user_data) +{ + char buf[5000]; + + if (pipe_read_ioc) + g_io_channel_read_chars(pipe_read_ioc, buf, sizeof(buf), NULL, NULL); + + gam_error_check(); +} + +static void +gam_setup_error_handler (void) +{ + int signal_pipe[2]; + GSource *source; + + if (pipe(signal_pipe) != -1) { + pipe_read_ioc = g_io_channel_unix_new(signal_pipe[0]); + pipe_write_ioc = g_io_channel_unix_new(signal_pipe[1]); + + g_io_channel_set_flags(pipe_read_ioc, G_IO_FLAG_NONBLOCK, NULL); + g_io_channel_set_flags(pipe_write_ioc, G_IO_FLAG_NONBLOCK, NULL); + + source = g_io_create_watch(pipe_read_ioc, G_IO_IN | G_IO_HUP | G_IO_ERR); + g_source_set_callback(source, gam_error_signal_pipe_handler, NULL, NULL); + + g_source_attach(source, NULL); + g_source_unref(source); + } +} +#endif + +void +gam_got_signal() +{ +#ifdef GAM_DEBUG_ENABLED + /* Wake up main loop */ + if (pipe_write_ioc) { + g_io_channel_write_chars(pipe_write_ioc, "a", 1, NULL, NULL); + g_io_channel_flush(pipe_write_ioc, NULL); + } +#endif +} + + + /** * gam_server_init: * @loop: the main event loop of the daemon @@ -533,11 +597,11 @@ gam_server_init(GMainLoop * loop, const * Register the timeout checking function */ if (no_timeout == 0) - g_timeout_add(1000, (GSourceFunc) gam_connections_check, NULL); + gam_schedule_server_timeout (); #ifdef GAM_DEBUG_ENABLED - g_timeout_add(1000, (GSourceFunc) gam_error_check, NULL); + gam_setup_error_handler (); #endif - + return TRUE; } Index: server/gam_server.h =================================================================== RCS file: /cvs/gnome/gamin/server/gam_server.h,v retrieving revision 1.11 diff -u -p -r1.11 gam_server.h --- server/gam_server.h 16 Aug 2005 20:44:17 -0000 1.11 +++ server/gam_server.h 5 Sep 2006 14:02:44 -0000 @@ -33,6 +33,7 @@ typedef enum pollHandlerMode { } pollHandlerMode; gboolean gam_init_subscriptions (void); +gboolean gam_server_use_timeout (void); gboolean gam_add_subscription (GamSubscription *sub); gboolean gam_remove_subscription (GamSubscription *sub); int gam_server_num_listeners (void); @@ -48,6 +49,7 @@ void gam_server_emit_event int force); void gam_shutdown (void); void gam_show_debug (void); +void gam_got_signal (void); void gam_server_install_kernel_hooks (GamKernelHandler name, gboolean (*add)(GamSubscription *sub),