[Mono-devel-list] A workaround proposal for FreeBSD shared mutex problem

Bill Middleton flashdict at gmail.com
Fri Apr 8 13:18:18 EDT 2005


I'd like to get some feedback and advice related to a workaround I'm
considering for the problems with FreeBSD pthreads library which
limits the ability to share mutexes between processes.  For details
about the problem, you can see Tom's summary on the previous thread:

http://lists.ximian.com/archives/public/mono-devel-list/2005-April/011316.html

After digging around a bit, I've discovered that the Wapi daemon
(daemon.c) marks the handle for a given child process as signalled if
_POSIX__THREAD_PROCESS_SHARED is not defined, which is currently the
default for everyone in svn, and will remain the default for FreeBSD
even after it is re-enabled for everyone else.  In daemon.c, this
signalling is accomplished thusly:

      _wapi_shared_data[segment]->handles[idx].signalled=TRUE;

What this enables me to do then, for FreeBSD, is detect if a given
handle has been signalled, which means it's a fork/execve'd process, 
and avoid destroying the mutex and pthread_cond if so, by simply
return()'ing before the call to mono_mutex_destroy() and
pthread_cond_destroy(), both of which will SIGABRT on FreeBSD if
called on the shared segment.

I accomplish this via the following simple (but ugly) patch, which
already I've sent to the bsd# list for precursory testing.

My question is, is this an acceptable workaround?  Ideally, this code
should be somehow #ifdef'd for  _POSIX__THREAD_PROCESS_SHARED, but
other than returning immedietly, as I've done here, I'm not sure what
else can be done.  Note that the return statement follows the call to
close_private(handle) and the handle has been marked as UNUSED, so it
shouldn't leak (I hope).

This patch gets FreeBSD a minimally working
System.Diagnostics.Process, although the threads still tend to wait
around a long time.  Also, I'm looking for advice on how to accomplish
this same sort of effect in wait.c, which gives us errors for Pipe()
and friends.

The threading code is pretty gnarly for a guy like me, but this sort
of fix seems the only viable alternative right now, as
process-sharable mutexes for FreeBSD are only available for the very
latest a most cutting-edge FreeBSD release, and they're not posix.

Thanks for any advice.  On a positive note, my working copy on FreeBSD
now uses a sigaltstack() and ucontext, as preferred, and only fails
three tests.  However, there are no tests for System.Diagnostics yet. 
:)

Regards,

Bill Middleton


Index: handles.c
===================================================================
--- handles.c   (revision 42643)
+++ handles.c   (working copy)
@@ -712,6 +712,22 @@
                 * now, but pthreads doesn't have a
                 * "unlock_and_destroy" atomic function.
                 */
+
+#if defined(__FreeBSD__)
+               if(_wapi_shared_data[segment]->handles[idx].signalled==TRUE)
+                       return;
+#endif
+
                thr_ret = mono_mutex_destroy (&_wapi_handle_get_shared_segment
(segment)->handles[idx].signal_mutex);
                g_assert (thr_ret == 0);



More information about the Mono-devel-list mailing list