00001 // Copyright (C) 2001, Compaq Computer Corporation 00002 00003 // This file is part of Vesta. 00004 00005 // Vesta is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 00010 // Vesta is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // Lesser General Public License for more details. 00014 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with Vesta; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 // Last modified on Sun May 22 21:41:14 EDT 2005 by ken@xorian.net 00020 // modified on Fri Aug 28 09:07:40 PDT 1998 by heydon 00021 00022 // A version of the "ThreadStart" interface to be linked with the 00023 // DECwest garbage collector. 00024 00025 #include <signal.h> 00026 00027 #include "gc.h" 00028 #include "Basics.H" 00029 #include "ThreadStart.H" 00030 00031 void *Basics::ThreadStart_Callback(void *arg) throw () 00032 { 00033 void *res; 00034 /* Note: we can no longer use GC_THREAD_START/_END because they require 00035 non-portable pthread routines that Mike did not implement in his 00036 pthread library. Instead, we simulate their effects. For this to 00037 work, no forked thread should call pthread_exit() or be canceled. */ 00038 // GC_THREAD_START 00039 gc_note_thread(); 00040 00041 // save arguments locally 00042 Basics::ForkArgs *forkArgs = (ForkArgs *)arg; 00043 00044 // signal parent that child has started 00045 forkArgs->mu.lock(); 00046 forkArgs->started = true; 00047 forkArgs->untilStarted.signal(); 00048 forkArgs->mu.unlock(); 00049 00050 // ignore the PIPE signal 00051 signal(SIGPIPE, SIG_IGN); 00052 signal(SIGQUIT, SIG_DFL); 00053 signal(SIGABRT, SIG_DFL); 00054 signal(SIGSEGV, SIG_DFL); 00055 signal(SIGILL, SIG_DFL); 00056 signal(SIGBUS, SIG_DFL); 00057 00058 // invoke the real procedure 00059 try { 00060 res = (*(forkArgs->proc))(forkArgs->arg); 00061 } catch (...) { gc_delete_thread_rec(0); throw; } 00062 // GC_THREAD_END 00063 gc_delete_thread_rec(0); 00064 00065 return res; 00066 } 00067 00068 void Basics::ThreadStart_WaitForChild(Basics::ForkArgs *forkArgs) throw () 00069 { 00070 forkArgs->mu.lock(); 00071 while (!forkArgs->started) { 00072 forkArgs->untilStarted.wait(forkArgs->mu); 00073 } 00074 forkArgs->mu.unlock(); 00075 } 00076