referring to something like c:\.
* dcrt0.cc (dll_crt0_1): Move uinfo initialization prior to sig_send
initialization to give signal thread a chance to finish.
* debug.cc (WFSO): Move to sigproc.cc
(WFMO): Ditto.
* exceptions.cc (interruptible): Allocate slightly more space for directory
just for paranoia's sake.
(call_handler): Eliminate nonmain argument. Determine if main thread has set a
frame pointer and use it if so.
(sig_handle): Eliminate nonmain argument.
* net.cc: Record frame information in appropriate routines throughout.
* select.cc (select): Ditto.
* sigproc.cc: Use sigthread structure to record mainthread id throughout.
(sig_send): Record frame information for signal handler.
(wait_sig): Reflect argument change in sig_handle.
(WFSO): Move here and record frame information for signal handler.
(WFMO): Ditto.
* sigproc.h: Implement new "sigthread" class. Implement "sigframe" class for
manipulating signal frame info.
* thread.cc (__pthread_kill): Use standard _kill() function rather than calling
sig_send directly.
* winsup.h: Eliminate ebp element from signal_dispatch class.
+Wed May 17 01:05:52 2000 Christopher Faylor <cgf@cygnus.com>
+
+ * path.cc (mount_info::cygdrive_posix_path): Don't add trailing slash
+ if referring to something like c:\.
+ * dcrt0.cc (dll_crt0_1): Move uinfo initialization prior to sig_send
+ initialization to give signal thread a chance to finish.
+ * debug.cc (WFSO): Move to sigproc.cc
+ (WFMO): Ditto.
+ * exceptions.cc (interruptible): Allocate slightly more space for
+ directory just for paranoia's sake.
+ (call_handler): Eliminate nonmain argument. Determine if main thread
+ has set a frame pointer and use it if so.
+ (sig_handle): Eliminate nonmain argument.
+ * net.cc: Record frame information in appropriate routines throughout.
+ * select.cc (select): Ditto.
+ * sigproc.cc: Use sigthread structure to record mainthread id
+ throughout.
+ (sig_send): Record frame information for signal handler.
+ (wait_sig): Reflect argument change in sig_handle.
+ (WFSO): Move here and record frame information for signal handler.
+ (WFMO): Ditto.
+ * sigproc.h: Implement new "sigthread" class. Implement "sigframe"
+ class for manipulating signal frame info.
+ * thread.cc (__pthread_kill): Use standard _kill() function rather than
+ calling sig_send directly.
+ * winsup.h: Eliminate ebp element from signal_dispatch class.
+
Tue May 16 23:39:00 2000 Corinna Vinschen <corinna@vinschen.de>
Patch suggested by John Rowley <wjr@bgs.ac.uk>
* fhandler_tape.cc (fhandler_dev_tape::ioctl): Check
- for filemark feature on MTWEOF operation.
+ for filemark feature on MTWEOF operation.
Tue May 16 11:49:13 2000 Christopher Faylor <cgf@cygnus.com>
set_errno (0);
debug_printf ("user_data->main %p", user_data->main);
+ /* Initialize uid, gid. */
+ uinfo_init ();
+
/* Flush signals and ensure that signal thread is up and running. Can't
do this for noncygwin case since the signal thread is blocked due to
LoadLibrary serialization. */
if (!dynamically_loaded)
sig_send (NULL, __SIGFLUSH);
- /* Initialize uid, gid. */
- uinfo_init ();
-
if (user_data->main && !dynamically_loaded)
exit (user_data->main (argc, argv, *user_data->envptr));
}
#define NO_DEBUG_DEFINES
#include "winsup.h"
#include "exceptions.h"
-#include "sync.h"
static muto NO_COPY *threadname_lock = NULL;
#define lock_threadname() \
iscygthread()
{
DWORD tid = GetCurrentThreadId ();
- if (tid != maintid)
+ if (tid != mainthread.id)
for (DWORD i = 0; i < NTHREADS && threads[i].name != NULL; i++)
if (threads[i].id == tid)
return 1;
return ret;
}
#endif /*DEBUGGING*/
-
-extern "C" {
-/* Provide a stack frame when calling WaitFor* functions */
-
-#undef WaitForSingleObject
-
-DWORD __stdcall
-WFSO (HANDLE hHandle, DWORD dwMilliseconds)
-{
- DWORD ret;
- ret = WaitForSingleObject (hHandle, dwMilliseconds);
- return ret;
-}
-
-#undef WaitForMultipleObjects
-
-DWORD __stdcall
-WFMO (DWORD nCount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds)
-{
- DWORD ret;
- ret = WaitForMultipleObjects (nCount, lpHandles, fWaitAll, dwMilliseconds);
- return ret;
-}
-}
#define DECLSPEC_IMPORT
#include <imagehlp.h>
#include "autoload.h"
-#include "sync.h"
char debugger_command[2 * MAX_PATH + 20];
if (!VirtualQuery ((LPCVOID) pc, &m, sizeof m))
sigproc_printf ("couldn't get memory info, %E");
- char *checkdir = (char *) alloca (windows_system_directory_length + 2);
+ char *checkdir = (char *) alloca (windows_system_directory_length + 4);
+ memset (checkdir, 0, sizeof (checkdir));
# define h ((HMODULE) m.AllocationBase)
if (h == user_data->hmodule)
res = 1;
sigsave.func = (void (*)(int)) handler;
sigsave.sig = sig;
sigsave.saved_errno = -1; // Flag: no errno to save
- sigsave.ebp = 0;
}
static void
}
static int
-call_handler (int sig, struct sigaction& siga, void *handler, int nonmain)
+call_handler (int sig, struct sigaction& siga, void *handler)
{
CONTEXT cx;
- DWORD ebp;
int interrupted = 1;
HANDLE hth = NULL;
+ DWORD ebp;
int res;
+ int locked;
- if (!nonmain)
- ebp = sigsave.ebp;
+ if (!mainthread.lock)
+ locked = 0;
else
{
+ mainthread.lock->acquire ();
+ locked = 1;
+ }
+
+ if (mainthread.frame)
+ ebp = mainthread.frame;
+ else
+ {
+ if (locked)
+ {
+ mainthread.lock->release ();
+ locked = 0;
+ }
+
hth = myself->getthread2signal ();
/* Suspend the thread which will receive the signal. But first ensure that
this thread doesn't have the sync_proc_subproc and mask_sync mutos, since
muto *m;
/* FIXME: Make multi-thread aware */
for (m = muto_start.next; m != NULL; m = m->next)
- if (m->unstable () || m->owner () == maintid)
+ if (m->unstable () || m->owner () == mainthread.id)
goto keep_looping;
+ if (mainthread.frame)
+ {
+ ebp = mainthread.frame; /* try to avoid a race */
+ goto ebp_set;
+ }
+
break;
keep_looping:
ebp = cx.Ebp;
}
- if (hExeced != NULL || (nonmain && interruptible (cx.Eip)))
+ebp_set:
+ if (hExeced != NULL || (!mainthread.frame && interruptible (cx.Eip)))
interrupt_now (&cx, sig, siga, handler);
else if (!interrupt_on_return (ebp, sig, siga, handler))
{
sigproc_printf ("ResumeThread returned %d", res);
}
+ if (locked)
+ mainthread.lock->release ();
+
sigproc_printf ("returning %d", interrupted);
return interrupted;
}
}
int __stdcall
-sig_handle (int sig, int nonmain)
+sig_handle (int sig)
{
int rc = 0;
dosig:
/* Dispatch to the appropriate function. */
sigproc_printf ("signal %d, about to call %p", sig, thissig.sa_handler);
- rc = call_handler (sig, thissig, handler, nonmain);
+ rc = call_handler (sig, thissig, handler);
done:
sigproc_printf ("returning %d", rc);
#include "winsup.h"
#include <stdlib.h>
-#include "sync.h"
/* we provide these stubs to call into a user's
provided malloc if there is one - otherwise
{
fhandler_socket *h = (fhandler_socket *) dtable[fd];
sockaddr_in sin;
+ sigframe thisframe (mainthread, 0);
if (get_inet_addr (to, tolen, &sin, &tolen) == 0)
return -1;
int *fromlen)
{
fhandler_socket *h = (fhandler_socket *) dtable[fd];
+ sigframe thisframe (mainthread, 0);
debug_printf ("recvfrom %d", h->get_socket ());
int res;
fhandler_socket *sock = get (fd);
sockaddr_in sin;
+ sigframe thisframe (mainthread, 0);
if (get_inet_addr (name, namelen, &sin, &namelen) == 0)
return -1;
cygwin_accept (int fd, struct sockaddr *peer, int *len)
{
int res = -1;
+ sigframe thisframe (mainthread, 0);
fhandler_socket *sock = get (fd);
if (sock)
cygwin_shutdown (int fd, int how)
{
int res = -1;
-
+ sigframe thisframe (mainthread, 0);
fhandler_socket *sock = get (fd);
if (sock)
cygwin_recv (int fd, void *buf, int len, unsigned int flags)
{
fhandler_socket *h = (fhandler_socket *) dtable[fd];
+ sigframe thisframe (mainthread, 0);
int res = recv (h->get_socket (), (char *) buf, len, flags);
if (res == SOCKET_ERROR)
cygwin_send (int fd, const void *buf, int len, unsigned int flags)
{
fhandler_socket *h = (fhandler_socket *) dtable[fd];
+ sigframe thisframe (mainthread, 0);
int res = send (h->get_socket (), (const char *) buf, len, flags);
if (res == SOCKET_ERROR)
{
int res = -1;
SOCKET fd2s;
+ sigframe thisframe (mainthread, 0);
int res_fd = dtable.find_unused_handle ();
if (res_fd == -1)
cygwin_rresvport (int *port)
{
int res = -1;
+ sigframe thisframe (mainthread, 0);
int res_fd = dtable.find_unused_handle ();
if (res_fd == -1)
{
int res = -1;
SOCKET fd2s;
+ sigframe thisframe (mainthread, 0);
int res_fd = dtable.find_unused_handle ();
if (res_fd == -1)
int
fhandler_socket::read (void *ptr, size_t len)
{
+ sigframe thisframe (mainthread);
int res = recv (get_socket (), (char *) ptr, len, 0);
if (res == SOCKET_ERROR)
{
int
fhandler_socket::write (const void *ptr, size_t len)
{
+ sigframe thisframe (mainthread);
int res = send (get_socket (), (const char *) ptr, len, 0);
if (res == SOCKET_ERROR)
{
fhandler_socket::close ()
{
int res = 0;
+ sigframe thisframe (mainthread);
if (closesocket (get_socket ()))
{
int res;
struct ifconf *ifc;
struct ifreq *ifr;
+ sigframe thisframe (mainthread);
switch (cmd)
{
The cygdrive prefix always ends with a trailing slash so
the drive letter is added after the path. */
dst[len++] = tolower (src[0]);
- if (!src[2])
+ if (!src[2] || (SLASH_P (src[2]) && !src[3]))
dst[len++] = '\000';
else
{
int keep_rel_p)
{
int src_path_len = strlen (src_path);
- int trailing_slash_p = (src_path_len > 0
- && SLASH_P (src_path[src_path_len - 1]));
- int relative_path_p = (! SLASH_P (*src_path)
- && strchr (src_path, ':') == NULL);
+ int relative_path_p = !isabspath (src_path);
+ int trailing_slash_p;
+ if (src_path_len <= 1)
+ trailing_slash_p = 0;
+ else
+ {
+ const char *lastchar = src_path + src_path_len - 1;
+ trailing_slash_p = SLASH_P (*lastchar) && lastchar[-1] != ':';
+ }
+
debug_printf ("conv_to_posix_path (%s, %s)", src_path,
keep_rel_p ? "keep-rel" : "no-keep-rel");
MALLOC_CHECK;
caller must want an absolute path (otherwise we would have returned
above). So we always return an absolute path at this point. */
if ((isalpha (pathbuf[0])) && (pathbuf[1] == ':'))
- cygdrive_posix_path (pathbuf, posix_path, trailing_slash_p &&
- pathbuflen > 3);
+ cygdrive_posix_path (pathbuf, posix_path, trailing_slash_p);
else
{
/* The use of src_path and not pathbuf here is intentional.
fd_set *dummy_readfds = allocfd_set (n);
fd_set *dummy_writefds = allocfd_set (n);
fd_set *dummy_exceptfds = allocfd_set (n);
+ sigframe thisframe (mainthread, 0);
#if 0
if (n > FD_SETSIZE)
#include <errno.h>
#include <stdlib.h>
#include "winsup.h"
-#include "sync.h"
extern BOOL allow_ntsec;
muto NO_COPY *sync_proc_subproc = NULL; // Control access to subproc stuff
-DWORD NO_COPY maintid = 0; // ID of the main thread
+sigthread NO_COPY mainthread; // ID of the main thread
DWORD NO_COPY sigtid = 0; // ID of the signal thread
int NO_COPY pending_signals = 0; // TRUE if signals pending
to a signal handler function. */
signal_arrived = CreateEvent(&sec_none_nih, TRUE, FALSE, NULL);
- maintid = GetCurrentThreadId ();// For use in determining if signals
+ mainthread.id = GetCurrentThreadId ();// For use in determining if signals
// should be blocked.
if (!(hwait_sig = makethread (wait_sig, NULL, 0, "sig")))
HANDLE thiscatch = NULL;
HANDLE thiscomplete = NULL;
BOOL wait_for_completion;
- extern signal_dispatch sigsave;
+ sigframe thisframe;
if (p == myself_nowait_nonmain)
- p = (tid == maintid) ? myself : myself_nowait;
+ p = (tid == mainthread.id) ? myself : myself_nowait;
if (!(its_me = (p == NULL || p == myself || p == myself_nowait)))
wait_for_completion = FALSE;
else
{
if (!wait_for_completion)
thiscatch = sigcatch_nosync;
- else if (tid != maintid)
+ else if (tid != mainthread.id)
{
thiscatch = sigcatch_nonmain;
thiscomplete = sigcomplete_nonmain;
{
thiscatch = sigcatch_main;
thiscomplete = sigcomplete_main;
- sigsave.ebp = ebp ?: (DWORD) __builtin_frame_address (1);
+ thisframe.set (mainthread);
}
}
else if (!(thiscatch = getsem (p, "sigcatch", 0, 0)))
/* Signalled from a child process that it has stopped */
case __SIGCHILDSTOPPED:
sip_printf ("Received child stopped notification");
- dispatched |= sig_handle (SIGCHLD, rc);
+ dispatched |= sig_handle (SIGCHLD);
if (proc_subproc (PROC_CHILDSTOPPED, 0))
dispatched |= 1;
break;
/* A normal UNIX signal */
default:
sip_printf ("Got signal %d", sig);
- int wasdispatched = sig_handle (sig, rc);
+ int wasdispatched = sig_handle (sig);
dispatched |= wasdispatched;
if (sig == SIGCHLD && wasdispatched)
dispatched_sigchld = 1;
{
case 0:
SetEvent (sigcomplete_main);
-sigproc_printf ("signalled sigcomplete_main %p", sigcomplete_main);
break;
case 1:
ReleaseSemaphore (sigcomplete_nonmain, 1, NULL);
-sigproc_printf ("signalled sigcomplete_nonmain %p", sigcomplete_nonmain);
break;
default:
-sigproc_printf ("Did not signal anyone");
/* Signal from another process. No need to synchronize. */
break;
}
sip_printf ("done");
return 0;
}
+
+extern "C" {
+/* Provide a stack frame when calling WaitFor* functions */
+
+#undef WaitForSingleObject
+
+DWORD __stdcall
+WFSO (HANDLE hHandle, DWORD dwMilliseconds)
+{
+ DWORD ret;
+ sigframe thisframe (mainthread);
+ ret = WaitForSingleObject (hHandle, dwMilliseconds);
+ return ret;
+}
+
+#undef WaitForMultipleObjects
+
+DWORD __stdcall
+WFMO (DWORD nCount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds)
+{
+ DWORD ret;
+ sigframe thisframe (mainthread);
+ ret = WaitForMultipleObjects (nCount, lpHandles, fWaitAll, dwMilliseconds);
+ return ret;
+}
+}
HANDLE thread_ev;
} waitq;
+class muto;
+
+struct sigthread
+{
+ DWORD id;
+ DWORD frame;
+ muto *lock;
+ sigthread () : id (0), frame (0), lock (0) {}
+};
+
+class sigframe
+{
+private:
+ sigthread *st;
+
+public:
+ void set (sigthread &t, int up = 1)
+ {
+ if (!t.lock)
+ t.lock = new_muto (FALSE, "sigthread");
+ t.lock->acquire ();
+ st = &t;
+ t.frame = (DWORD) (up ? __builtin_frame_address (1) :
+ __builtin_frame_address (0));
+ t.lock->release ();
+ }
+
+ sigframe () {st = NULL;}
+ sigframe (sigthread &t, int up = 1)
+ {
+ if (!t.frame || t.id == GetCurrentThreadId ())
+ set (t, up);
+ else
+ st = NULL;
+ }
+ ~sigframe ()
+ {
+ if (st)
+ {
+ st->lock->acquire ();
+ st->frame = 0;
+ st->lock->release ();
+ st = NULL;
+ }
+ }
+};
+
+extern sigthread mainthread;
extern HANDLE signal_arrived;
BOOL __stdcall my_parent_is_alive ();
extern "C" int __stdcall sig_dispatch_pending (int force = FALSE) __asm__ ("sig_dispatch_pending");
extern "C" void __stdcall set_process_mask (sigset_t newmask);
-int __stdcall sig_handle (int, int);
+int __stdcall sig_handle (int);
void __stdcall sig_clear (int);
void __stdcall sig_set_pending (int);
int __stdcall handle_sigsuspend (sigset_t);
extern char myself_nowait_dummy[];
extern char myself_nowait_nonmain_dummy[];
-extern DWORD maintid;
extern HANDLE hExeced; // Process handle of new window
// process created by spawn_guts()
#include <errno.h>
#include <stdlib.h>
#include "winsup.h"
-#include "sync.h"
muto NO_COPY muto_start;
/* Constructor */
-muto::muto(int inh, const char *s) : sync (0), visits(0), waiters(-1), tid (0), next (NULL)
+muto::muto (int inh, const char *s) : sync (0), visits(0), waiters(-1), tid (0), next (NULL)
{
/* Create event which is used in the fallback case when blocking is necessary */
if (!(bruteforce = CreateEvent (inh ? &sec_all_nih : &sec_none_nih, FALSE, FALSE, name)))
/* Use a statically allocated buffer as the storage for a muto */
#define new_muto(__inh, __name) \
({ \
- static NO_COPY muto __mbuf; \
+ static __attribute__((section(".data_cygwin_nocopy"))) muto __mbuf; \
(void) new ((char *) &__mbuf) muto (__inh, __name); \
__mbuf.next = muto_start.next; \
muto_start.next = &__mbuf; \
read_handler (int fd, void *ptr, size_t len)
{
int res;
+ sigframe thisframe (mainthread);
fhandler_base *fh = dtable[fd];
if (dtable.not_open (fd))
if (item->sigs)
myself->setthread2signal (item);
- int rval = sig_send (myself, sig);
+ int rval = _kill (myself->pid, sig);
// unlock myself
return rval;
/* Now that pinfo has been defined, include... */
#include "debug.h"
+#include "sync.h"
#include "sigproc.h"
#include "fhandler.h"
#include "path.h"
void (*func) (int);
int sig;
int saved_errno;
- DWORD ebp;
DWORD oldmask;
DWORD retaddr;
DWORD *retaddr_on_stack;