diff options
author | Dick Porter <dick@acm.org> | 2004-05-04 20:20:16 +0400 |
---|---|---|
committer | Dick Porter <dick@acm.org> | 2004-05-04 20:20:16 +0400 |
commit | 9d0125942b0acbf05755a942a58172dc91678c61 (patch) | |
tree | 3d38edffa9cbb79268289beed1109c8eaec3f28a | |
parent | 629250586185bb50b176ca2f435ae40d1a614232 (diff) |
2004-05-04 Dick Porter <dick@ximian.com>
* daemon.c (read_message): Return FALSE on error so the GSource
callback itself can return FALSE. Cures the infinite loop poll()
warning on MacosX.
* shared.c: Fix some daemon startup race conditions.
svn path=/trunk/mono/; revision=26704
-rw-r--r-- | mono/io-layer/ChangeLog | 7 | ||||
-rw-r--r-- | mono/io-layer/daemon.c | 11 | ||||
-rw-r--r-- | mono/io-layer/shared.c | 78 |
3 files changed, 68 insertions, 28 deletions
diff --git a/mono/io-layer/ChangeLog b/mono/io-layer/ChangeLog index 497593eaa2d..a555184c039 100644 --- a/mono/io-layer/ChangeLog +++ b/mono/io-layer/ChangeLog @@ -1,3 +1,10 @@ +2004-05-04 Dick Porter <dick@ximian.com> + + * daemon.c (read_message): Return FALSE on error so the GSource + callback itself can return FALSE. Cures the infinite loop poll() + warning on MacosX. + * shared.c: Fix some daemon startup race conditions. + 2004-04-29 Miguel de Icaza <miguel@ximian.com> * io.c (CopyFile): Use 32k buffers to copy the file instead of 2k, diff --git a/mono/io-layer/daemon.c b/mono/io-layer/daemon.c index c7383751692..01fb5da616d 100644 --- a/mono/io-layer/daemon.c +++ b/mono/io-layer/daemon.c @@ -1095,9 +1095,10 @@ static void process_process_fork (GIOChannel *channel, ChannelData *channel_data * @open_handles: An array of handles referenced by this client * * Read a message (A WapiHandleRequest) from a client and dispatch - * whatever it wants to the process_* calls. + * whatever it wants to the process_* calls. Return TRUE if the message + * was read successfully, FALSE otherwise. */ -static void read_message (GIOChannel *channel, ChannelData *channel_data) +static gboolean read_message (GIOChannel *channel, ChannelData *channel_data) { WapiHandleRequest req; int fds[3]={0, 1, 2}; @@ -1114,7 +1115,7 @@ static void read_message (GIOChannel *channel, ChannelData *channel_data) g_io_channel_unix_get_fd (channel)); #endif rem_fd (channel, channel_data); - return; + return(FALSE); } #ifdef DEBUG @@ -1168,6 +1169,8 @@ static void read_message (GIOChannel *channel, ChannelData *channel_data) close (fds[1]); close (fds[2]); } + + return(TRUE); } /* @@ -1219,7 +1222,7 @@ static gboolean fd_activity (GIOChannel *channel, GIOCondition condition, g_message ("reading data on fd %d", fd); #endif - read_message (channel, channel_data); + return(read_message (channel, channel_data)); } return(TRUE); } diff --git a/mono/io-layer/shared.c b/mono/io-layer/shared.c index 22713e3618e..3391d39719c 100644 --- a/mono/io-layer/shared.c +++ b/mono/io-layer/shared.c @@ -258,17 +258,20 @@ try_again: } if(statbuf.st_size < wanted_size) { + close (fd); + if(created && *created==TRUE) { #ifdef HAVE_LARGE_FILE_SUPPORT - /* Keep gcc quiet... */ - g_critical (G_GNUC_PRETTY_FUNCTION ": shared file [%s] is not big enough! (found %lld, need %d bytes)", filename, statbuf.st_size, wanted_size); + /* Keep gcc quiet... */ + g_critical (G_GNUC_PRETTY_FUNCTION ": shared file [%s] is not big enough! (found %lld, need %d bytes)", filename, statbuf.st_size, wanted_size); #else - g_critical (G_GNUC_PRETTY_FUNCTION ": shared file [%s] is not big enough! (found %ld, need %d bytes)", filename, statbuf.st_size, wanted_size); + g_critical (G_GNUC_PRETTY_FUNCTION ": shared file [%s] is not big enough! (found %ld, need %d bytes)", filename, statbuf.st_size, wanted_size); #endif - if(created && *created==TRUE) { unlink (filename); + return(-1); + } else { + /* We didn't create it, so just try opening it again */ + goto try_again; } - close (fd); - return(-1); } return(fd); @@ -362,6 +365,7 @@ map_again: * out. This will let the calling code delete * the shared segments and try again. */ + g_warning ("The handle daemon is stuck closing"); return(FALSE); } @@ -418,22 +422,6 @@ map_again: g_message (G_GNUC_PRETTY_FUNCTION ": Daemon pid %d", pid); #endif #endif /* !VALGRINDING */ - } else { - /* Do some sanity checking on the shared memory we - * attached - */ - if(!((*data)->daemon_running==DAEMON_STARTING || - (*data)->daemon_running==DAEMON_RUNNING || - (*data)->daemon_running==DAEMON_DIED_AT_STARTUP) || -#ifdef NEED_LINK_UNLINK - (strncmp ((*data)->daemon, "/tmp/mono-handle-daemon-", - 24)!=0)) { -#else - (strncmp ((*data)->daemon+1, "mono-handle-daemon-", 19)!=0)) { -#endif - g_warning ("Shared memory sanity check failed."); - return(FALSE); - } } for(tries=0; (*data)->daemon_running==DAEMON_STARTING && tries < 100; @@ -451,11 +439,33 @@ map_again: } if(tries==100 && (*data)->daemon_running==DAEMON_STARTING) { /* Daemon didnt get going */ + struct timespec sleepytime; + if(data_created==TRUE) { _wapi_shm_destroy (); } - g_warning ("The handle daemon didnt start up properly"); - return(FALSE); + + /* Daemon didn't get going, give it a few ms and try + * again. + */ + + munmap (*data, data_size); + munmap (*scratch, scratch_size); + + if(closing_tries++ == 5) { + /* Something must have gone wrong, so bail + * out. This will let the calling code delete + * the shared segments and try again. + */ + g_warning ("The handle daemon didnt start up properly"); + return(FALSE); + } + + sleepytime.tv_sec=0; + sleepytime.tv_nsec=10000000; /* 10ms */ + + nanosleep (&sleepytime, NULL); + goto map_again; } if((*data)->daemon_running==DAEMON_DIED_AT_STARTUP) { @@ -466,6 +476,26 @@ map_again: g_warning ("Handle daemon failed to start"); return(FALSE); } + + /* Do some sanity checking on the shared memory we + * attached + */ + if(((*data)->daemon_running!=DAEMON_RUNNING) || +#ifdef NEED_LINK_UNLINK + (strncmp ((*data)->daemon, "/tmp/mono-handle-daemon-", + 24)!=0)) { +#else + (strncmp ((*data)->daemon+1, "mono-handle-daemon-", 19)!=0)) { +#endif + g_warning ("Shared memory sanity check failed."); + g_warning("status: %d", (*data)->daemon_running); +#ifdef NEED_LINK_UNLINK + g_warning("daemon: [%s]", (*data)->daemon); +#else + g_warning("daemon: [%s]", (*data)->daemon+1); +#endif + return(FALSE); + } /* From now on, it's up to the daemon to delete the shared * memory segment |