Added timer on server exit to wait a bit for new clients.
Don't remove the socket until the registry is closed to avoid a race.
diff --git a/server/request.c b/server/request.c
index 623520d..7ed598f 100644
--- a/server/request.c
+++ b/server/request.c
@@ -60,12 +60,12 @@
struct master_socket
{
- struct object obj; /* object header */
+ struct object obj; /* object header */
+ struct timeout_user *timeout; /* timeout on last process exit */
};
static void master_socket_dump( struct object *obj, int verbose );
static void master_socket_poll_event( struct object *obj, int event );
-static void master_socket_destroy( struct object *obj );
static const struct object_ops master_socket_ops =
{
@@ -81,7 +81,7 @@
no_flush, /* flush */
no_get_file_info, /* get_file_info */
NULL, /* queue_async */
- master_socket_destroy /* destroy */
+ no_destroy /* destroy */
};
@@ -447,6 +447,11 @@
int len = sizeof(dummy);
int client = accept( master_socket->obj.fd, (struct sockaddr *) &dummy, &len );
if (client == -1) return;
+ if (sock->timeout)
+ {
+ remove_timeout_user( sock->timeout );
+ sock->timeout = NULL;
+ }
fcntl( client, F_SETFL, O_NONBLOCK );
create_process( client );
}
@@ -459,11 +464,6 @@
if (!do_it_once++) unlink( SOCKETNAME );
}
-static void master_socket_destroy( struct object *obj )
-{
- socket_cleanup();
-}
-
/* return the configuration directory ($WINEPREFIX or $HOME/.wine) */
const char *get_config_dir(void)
{
@@ -557,6 +557,7 @@
if (!(master_socket = alloc_object( &master_socket_ops, fd )))
fatal_error( "out of memory\n" );
+ master_socket->timeout = NULL;
set_select_events( &master_socket->obj, POLLIN );
/* setup msghdr structure constant fields */
@@ -581,14 +582,30 @@
}
}
-/* close the master socket and stop waiting for new clients */
-void close_master_socket(void)
+/* master socket timer expiration handler */
+static void close_socket_timeout( void *arg )
{
/* if a new client is waiting, we keep on running */
if (!check_select_events( master_socket->obj.fd, POLLIN ))
release_object( master_socket );
}
+/* close the master socket and stop waiting for new clients */
+void close_master_socket(void)
+{
+ struct timeval when;
+
+ if (master_socket_timeout == -1) return; /* just keep running forever */
+
+ if (master_socket_timeout)
+ {
+ gettimeofday( &when, 0 );
+ add_timeout( &when, master_socket_timeout * 1000 );
+ master_socket->timeout = add_timeout_user( &when, close_socket_timeout, NULL );
+ }
+ else close_socket_timeout( NULL ); /* close it right away */
+}
+
/* lock/unlock the master socket to stop accepting new clients */
void lock_master_socket( int locked )
{