* exceptions.cc (set_console_handler): Don't allocate

console_handler_thread_waiter.  It is obsolete.
(ctrl_c_handler): Don't use console_handler_thread_waiter.
* path.cc (hash_path_name): Fix handling of relative names.  Make case
insensitive.
* path.h (suffix_info): Use initializers.
* pinfo.h (_pinfo): Avoid initializers for null case.
* resource.cc (fill_rusage): Zero rest of rusage structure.
* security.cc (set_process_privileges): Don't reopen parent process.  Just use
hMainProc.
* signal.cc (signal): Track when a signal handler has been used.
(sigaction): Ditto.
* sigproc.cc (pchildren): Use default initializer.
(zombies): Ditto.
(sigproc_terminate): Avoid closing handles that will be closed on exit anyway.
(wait_sig): Send signal to "parent" on EXECing, not FORKing.
(wait_subproc): Send SIGCHLD here rather than in proc_wait to avoid potential
muto conflicts.
* sigproc.h (sigthread): Don't initialize to zero.  It's the default.
* spawn.cc (spawn_guts): Fill in resources from exec parent prior to
termination.
* sync.h (muto): Don't initialize to zero.
* syscalls.cc (close_all_files): Use one lock around entire loop and call
fhandler close/release stuff directly.
(_read): Don't use ready_for_read if there are not signal handlers active.
* dcrt0.cc (dll_crt0_1): Fix display of "title".
(do_exit): Use pinfo exit method to exit.
(__api_fatal): Ditto.
* exceptions.cc (signal_exit): Ditto.
* fork.cc (fork_child): Remove debugging stuff.  Use pinfo_fixup_after fork in
place of exec_fixup_after_fork.
* pinfo.cc (pinfo_fixup_after_fork): New method.
(pinfo_fixup_in_spawned_child): Ditto.
(_pinfo::exit): New method.
(_pinfo::init): Remove recursion.  Detect pathological case where pinfo
structure already exists for new pid.
* pinfo.h (_pinfo): Reorganize slightly.  Add new method and new function
declarations.
* sigproc.cc (proc_exists): Previous simplification was a little to simple.
Try harder to detect if a process exists.
(proc_terminate): Use PID_EXITED setting to determine if process is still
around.
(WFSO): Remove debugging statement.
(WFMO): Ditto.
* spawn.cc (exec_fixup_after_fork): Eliminate.
(spawn_guts): Always set old_title to NULL.  Is it really needed?  Move
hexec_proc to pinfo.cc.  Call pinfo_fixup_in_spawned_child to eliminate handle
link after a spawn.
* include/sys/cygwin.h: Remove PID_NOT_IN_USE.  Add PID_EXITED.
This commit is contained in:
Christopher Faylor 2000-10-15 01:37:07 +00:00
parent fdc614360f
commit 1dc16fc74b
19 changed files with 359 additions and 277 deletions

View File

@ -1,3 +1,60 @@
Sat Oct 14 21:24:16 2000 Christopher Faylor <cgf@cygnus.com>
* exceptions.cc (set_console_handler): Don't allocate
console_handler_thread_waiter. It is obsolete.
(ctrl_c_handler): Don't use console_handler_thread_waiter.
* path.cc (hash_path_name): Fix handling of relative names. Make case
insensitive.
* path.h (suffix_info): Use initializers.
* pinfo.h (_pinfo): Avoid initializers for null case.
* resource.cc (fill_rusage): Zero rest of rusage structure.
* security.cc (set_process_privileges): Don't reopen parent process.
Just use hMainProc.
* signal.cc (signal): Track when a signal handler has been used.
(sigaction): Ditto.
* sigproc.cc (pchildren): Use default initializer.
(zombies): Ditto.
(sigproc_terminate): Avoid closing handles that will be closed on exit
anyway.
(wait_sig): Send signal to "parent" on EXECing, not FORKing.
(wait_subproc): Send SIGCHLD here rather than in proc_wait to avoid
potential muto conflicts.
* sigproc.h (sigthread): Don't initialize to zero. It's the default.
* spawn.cc (spawn_guts): Fill in resources from exec parent prior to
termination.
* sync.h (muto): Don't initialize to zero.
* syscalls.cc (close_all_files): Use one lock around entire loop and
call fhandler close/release stuff directly.
(_read): Don't use ready_for_read if there are not signal handlers
active.
Sat Oct 14 12:24:24 2000 Christopher Faylor <cgf@cygnus.com>
* dcrt0.cc (dll_crt0_1): Fix display of "title".
(do_exit): Use pinfo exit method to exit.
(__api_fatal): Ditto.
* exceptions.cc (signal_exit): Ditto.
* fork.cc (fork_child): Remove debugging stuff. Use pinfo_fixup_after
fork in place of exec_fixup_after_fork.
* pinfo.cc (pinfo_fixup_after_fork): New method.
(pinfo_fixup_in_spawned_child): Ditto.
(_pinfo::exit): New method.
(_pinfo::init): Remove recursion. Detect pathological case where pinfo
structure already exists for new pid.
* pinfo.h (_pinfo): Reorganize slightly. Add new method and new
function declarations.
* sigproc.cc (proc_exists): Previous simplification was a little to
simple. Try harder to detect if a process exists.
(proc_terminate): Use PID_EXITED setting to determine if process is
still around.
(WFSO): Remove debugging statement.
(WFMO): Ditto.
* spawn.cc (exec_fixup_after_fork): Eliminate.
(spawn_guts): Always set old_title to NULL. Is it really needed? Move
hexec_proc to pinfo.cc. Call pinfo_fixup_in_spawned_child to eliminate
handle link after a spawn.
* include/sys/cygwin.h: Remove PID_NOT_IN_USE. Add PID_EXITED.
Sat Oct 14 10:54:00 2000 Corinna Vinschen <corinna@vinschen.de> Sat Oct 14 10:54:00 2000 Corinna Vinschen <corinna@vinschen.de>
* cygwin.din: Add symbol hstrerror. * cygwin.din: Add symbol hstrerror.

View File

@ -683,8 +683,8 @@ dll_crt0_1 ()
cygheap_fixup_in_child (spawn_info->parent, 1); cygheap_fixup_in_child (spawn_info->parent, 1);
if (!spawn_info->moreinfo->myself_pinfo || if (!spawn_info->moreinfo->myself_pinfo ||
!DuplicateHandle (hMainProc, spawn_info->moreinfo->myself_pinfo, !DuplicateHandle (hMainProc, spawn_info->moreinfo->myself_pinfo,
hMainProc, &h, 0, 0, hMainProc, &h, 0, 0,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
h = NULL; h = NULL;
set_myself (mypid, h); set_myself (mypid, h);
__argc = spawn_info->moreinfo->argc; __argc = spawn_info->moreinfo->argc;
@ -769,18 +769,6 @@ dll_crt0_1 ()
line = strcpy ((char *) alloca (strlen (line) + 1), line); line = strcpy ((char *) alloca (strlen (line) + 1), line);
/* Set new console title if appropriate. */
if (display_title && !dynamically_loaded)
{
char *cp = line;
if (strip_title_path)
for (char *ptr = cp; *ptr && *ptr != ' '; ptr++)
if (isdirsep (*ptr))
cp = ptr + 1;
set_console_title (cp);
}
/* Allocate fdtab */ /* Allocate fdtab */
dtable_init (); dtable_init ();
@ -823,6 +811,18 @@ dll_crt0_1 ()
/* Set up __progname for getopt error call. */ /* Set up __progname for getopt error call. */
__progname = __argv[0]; __progname = __argv[0];
/* Set new console title if appropriate. */
if (display_title && !dynamically_loaded)
{
char *cp = __progname;
if (strip_title_path)
for (char *ptr = cp; *ptr && *ptr != ' '; ptr++)
if (isdirsep (*ptr))
cp = ptr + 1;
set_console_title (cp);
}
cygwin_finished_initializing = 1; cygwin_finished_initializing = 1;
/* Call init of loaded dlls. */ /* Call init of loaded dlls. */
dlls.init (); dlls.init ();
@ -1057,9 +1057,8 @@ do_exit (int status)
shared_terminate (); shared_terminate ();
sigproc_printf ("calling ExitProcess %d", n);
minimal_printf ("winpid %d, exit %d", GetCurrentProcessId (), n); minimal_printf ("winpid %d, exit %d", GetCurrentProcessId (), n);
ExitProcess (n); myself->exit (n);
} }
extern "C" void extern "C" void
@ -1099,7 +1098,7 @@ __api_fatal (const char *fmt, ...)
#ifdef DEBUGGING #ifdef DEBUGGING
(void) try_to_debug (); (void) try_to_debug ();
#endif #endif
ExitProcess (1); myself->exit (1);
} }
extern "C" { extern "C" {

View File

@ -16,12 +16,22 @@ details. */
#endif #endif
extern "C" { extern "C" {
#ifndef DEBUGGING0
DWORD __stdcall WFSO (HANDLE, DWORD); DWORD __stdcall WFSO (HANDLE, DWORD);
DWORD __stdcall WFMO (DWORD, CONST HANDLE *, BOOL, DWORD); DWORD __stdcall WFMO (DWORD, CONST HANDLE *, BOOL, DWORD);
#else
DWORD __stdcall WFSO (const char *fn, int ln, HANDLE, DWORD);
DWORD __stdcall WFMO (const char *fn, int ln, DWORD, CONST HANDLE *, BOOL, DWORD);
#endif
} }
#ifndef DEBUGGING0
#define WaitForSingleObject WFSO #define WaitForSingleObject WFSO
#define WaitForMultipleObject WFMO #define WaitForMultipleObject WFMO
#else
#define WaitForSingleObject(a, b) WFSO (__FUNCTION__, __LINE__, a, b)
#define WaitForMultipleObject(a, b, c, d) WFMO (__FUNCTION__, __LINE__, a, b, c, d)
#endif
#if !defined(_DEBUG_H_) #if !defined(_DEBUG_H_)
#define _DEBUG_H_ #define _DEBUG_H_

View File

@ -47,7 +47,6 @@ static NO_COPY int exit_already = 0;
static NO_COPY muto *mask_sync = NULL; static NO_COPY muto *mask_sync = NULL;
HMODULE NO_COPY cygwin_hmodule; HMODULE NO_COPY cygwin_hmodule;
HANDLE NO_COPY console_handler_thread_waiter = NULL;
static const struct static const struct
{ {
@ -126,10 +125,6 @@ set_console_handler ()
sec_all.lpSecurityDescriptor = sec_all_nih.lpSecurityDescriptor = sec_all.lpSecurityDescriptor = sec_all_nih.lpSecurityDescriptor =
get_null_sd (); get_null_sd ();
/* Allocate the event needed for ctrl_c_handler synchronization with
wait_sig. */
if (!console_handler_thread_waiter)
CreateEvent (&sec_none_nih, TRUE, TRUE, NULL);
(void) SetConsoleCtrlHandler (ctrl_c_handler, FALSE); (void) SetConsoleCtrlHandler (ctrl_c_handler, FALSE);
if (!SetConsoleCtrlHandler (ctrl_c_handler, TRUE)) if (!SetConsoleCtrlHandler (ctrl_c_handler, TRUE))
system_printf ("SetConsoleCtrlHandler failed, %E"); system_printf ("SetConsoleCtrlHandler failed, %E");
@ -825,11 +820,6 @@ ctrl_c_handler (DWORD type)
if (type == CTRL_LOGOFF_EVENT) if (type == CTRL_LOGOFF_EVENT)
return TRUE; return TRUE;
/* Wait for sigproc_init to tell us that it's safe to send something.
This event will always be in a signalled state when wait_sig is
ready to process signals. */
(void) WaitForSingleObject (console_handler_thread_waiter, 5000);
if ((type == CTRL_CLOSE_EVENT) || (type == CTRL_SHUTDOWN_EVENT)) if ((type == CTRL_CLOSE_EVENT) || (type == CTRL_SHUTDOWN_EVENT))
/* Return FALSE to prevent an "End task" dialog box from appearing /* Return FALSE to prevent an "End task" dialog box from appearing
for each Cygwin process window that's open when the computer for each Cygwin process window that's open when the computer
@ -1005,7 +995,7 @@ signal_exit (int rc)
{ {
rc = EXIT_SIGNAL | (rc << 8); rc = EXIT_SIGNAL | (rc << 8);
if (exit_already++) if (exit_already++)
ExitProcess (rc); myself->exit (rc);
/* We'd like to stop the main thread from executing but when we do that it /* We'd like to stop the main thread from executing but when we do that it
causes random, inexplicable hangs. So, instead, we set up the priority causes random, inexplicable hangs. So, instead, we set up the priority

View File

@ -225,8 +225,6 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
{ {
debug_printf ("child is running. pid %d, ppid %d, stack here %p", debug_printf ("child is running. pid %d, ppid %d, stack here %p",
myself->pid, myself->ppid, __builtin_frame_address (0)); myself->pid, myself->ppid, __builtin_frame_address (0));
child_info_fork ch;
stack_base (ch);
/* Restore the inheritance state as in parent /* Restore the inheritance state as in parent
Don't call setuid here! The flags are already set. */ Don't call setuid here! The flags are already set. */
@ -240,9 +238,8 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
} }
sync_with_parent ("after longjmp.", TRUE); sync_with_parent ("after longjmp.", TRUE);
debug_printf ("hParent %p", hParent);
ProtectHandle (hParent); ProtectHandle (hParent);
// small_printf ("child 1 first_dll %p, load_dlls %d\n", first_dll, load_dlls); sigproc_printf ("hParent %p, child 1 first_dll %p, load_dlls %d\n", hParent, first_dll, load_dlls);
#ifdef DEBUGGING #ifdef DEBUGGING
char c; char c;
@ -270,9 +267,9 @@ debug_printf ("hParent %p", hParent);
MALLOC_CHECK; MALLOC_CHECK;
pinfo_fixup_after_fork ();
fdtab.fixup_after_fork (hParent); fdtab.fixup_after_fork (hParent);
signal_fixup_after_fork (); signal_fixup_after_fork ();
exec_fixup_after_fork ();
MALLOC_CHECK; MALLOC_CHECK;

View File

@ -66,7 +66,6 @@ typedef enum
/* Flags associated with process_state */ /* Flags associated with process_state */
enum enum
{ {
PID_NOT_IN_USE = 0x0000, // Free entry.
PID_IN_USE = 0x0001, // Entry in use. PID_IN_USE = 0x0001, // Entry in use.
PID_ZOMBIE = 0x0002, // Child exited: no parent wait. PID_ZOMBIE = 0x0002, // Child exited: no parent wait.
PID_STOPPED = 0x0004, // Waiting for SIGCONT. PID_STOPPED = 0x0004, // Waiting for SIGCONT.
@ -86,7 +85,8 @@ enum
// all execed or forked processes. // all execed or forked processes.
PID_UNUSED2 = 0x2000, // child has execed PID_UNUSED2 = 0x2000, // child has execed
PID_EXECED = 0x4000, // redirect to original pid info block PID_EXECED = 0x4000, // redirect to original pid info block
PID_NOREDIR = 0x8000 // don't redirect if execed PID_NOREDIR = 0x8000, // don't redirect if execed
PID_EXITED = 0x80000000 // Free entry.
}; };
#ifdef WINVER #ifdef WINVER

View File

@ -2396,8 +2396,8 @@ hash_path_name (unsigned long hash, const char *name)
{ {
char *nn, *newname = (char *) alloca (strlen (name) + 2); char *nn, *newname = (char *) alloca (strlen (name) + 2);
nn = strncpy (newname, name, 2); nn = strncpy (newname, name, 2);
if (islower (*nn)) if (isupper (*nn))
*newname = toupper (*nn); *newname = tolower (*nn);
*(nn += 2) = '\0'; *(nn += 2) = '\0';
name += 2; name += 2;
if (*name != '\\') if (*name != '\\')
@ -2415,12 +2415,12 @@ hash_path_name (unsigned long hash, const char *name)
Otherwise the inodes same will differ depending on whether a file is Otherwise the inodes same will differ depending on whether a file is
referenced with an absolute value or relatively. */ referenced with an absolute value or relatively. */
if (*name != '\\') if (!hash && !isabspath (name))
{ {
hash = cygcwd.get_hash (); hash = cygcwd.get_hash ();
if (name[0] == '.' && name[1] == '\0') if (name[0] == '.' && name[1] == '\0')
return hash; return hash;
hash = hash_path_name (hash, "\\"); hash += hash_path_name (hash, "\\");
} }
} }
@ -2429,7 +2429,8 @@ hashit:
\a\b\. but allow a single \ if that's all there is. */ \a\b\. but allow a single \ if that's all there is. */
do do
{ {
hash += *name + (*name << 17); int ch = tolower(*name);
hash += ch + (ch << 17);
hash ^= hash >> 2; hash ^= hash >> 2;
} }
while (*++name != '\0' && while (*++name != '\0' &&

View File

@ -12,7 +12,7 @@ struct suffix_info
{ {
const char *name; const char *name;
int addon; int addon;
suffix_info (const char *s, int addit = 0) {name = s, addon = addit;} suffix_info (const char *s, int addit = 0): name (s), addon (addit) {}
}; };
enum pathconv_arg enum pathconv_arg

View File

@ -24,11 +24,41 @@ details. */
#include "perprocess.h" #include "perprocess.h"
#include "environ.h" #include "environ.h"
#include "security.h" #include "security.h"
#include <assert.h>
static char NO_COPY pinfo_dummy[sizeof(pinfo)] = {0}; static char NO_COPY pinfo_dummy[sizeof(pinfo)] = {0};
pinfo NO_COPY myself ((_pinfo *)&pinfo_dummy); // Avoid myself != NULL checks pinfo NO_COPY myself ((_pinfo *)&pinfo_dummy); // Avoid myself != NULL checks
static HANDLE hexec_proc = NULL;
void __stdcall
pinfo_fixup_after_fork ()
{
if (hexec_proc)
CloseHandle (hexec_proc);
if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hexec_proc, 0,
TRUE, DUPLICATE_SAME_ACCESS))
{
system_printf ("couldn't save current process handle %p, %E", hMainProc);
hexec_proc = NULL;
}
}
void __stdcall
pinfo_fixup_in_spawned_child (HANDLE hchild)
{
HANDLE h;
if (!hexec_proc)
return;
if (!DuplicateHandle (hchild, hexec_proc, hMainProc, &h, 0, TRUE,
DUPLICATE_CLOSE_SOURCE))
system_printf ("couldn't close handle %p in child, %E", hexec_proc);
else
CloseHandle (h);
}
/* Initialize the process table. /* Initialize the process table.
This is done once when the dll is first loaded. */ This is done once when the dll is first loaded. */
@ -96,6 +126,14 @@ pinfo_init (char **envp)
debug_printf ("pid %d, pgid %d", myself->pid, myself->pgid); debug_printf ("pid %d, pgid %d", myself->pid, myself->pgid);
} }
void
_pinfo::exit (UINT n)
{
process_state = PID_EXITED;
sigproc_printf ("Calling ExitProcess %d", n);
ExitProcess (n);
}
struct sigaction& struct sigaction&
_pinfo::getsig(int sig) _pinfo::getsig(int sig)
{ {
@ -185,66 +223,82 @@ pinfo::init (pid_t n, DWORD create, HANDLE in_h)
return; return;
} }
int created; for (int i = 0; i < 10; i++)
char mapname[MAX_PATH];
__small_sprintf (mapname, "cygpid.%x", n);
int mapsize;
if (create & PID_EXECED)
mapsize = PINFO_REDIR_SIZE;
else
mapsize = sizeof (_pinfo);
if (in_h)
{ {
h = in_h; int created;
created = 0; char mapname[MAX_PATH];
} __small_sprintf (mapname, "cygpid.%x", n);
else if (!create)
{
/* CGF FIXME -- deal with inheritance after an exec */
h = OpenFileMappingA (FILE_MAP_READ | FILE_MAP_WRITE, FALSE, mapname);
created = 0;
}
else
{
h = CreateFileMapping ((HANDLE) 0xffffffff, &sec_all_nih,
PAGE_READWRITE, 0, mapsize, mapname);
created = h && GetLastError () != ERROR_ALREADY_EXISTS;
}
if (!h) int mapsize;
{ if (create & PID_EXECED)
if (create) mapsize = PINFO_REDIR_SIZE;
__seterrno (); else
procinfo = NULL; mapsize = sizeof (_pinfo);
return;
}
ProtectHandle1 (h, pinfo_shared_handle); if (in_h)
procinfo = (_pinfo *) MapViewOfFile (h, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); {
h = in_h;
created = 0;
}
else if (!create)
{
/* CGF FIXME -- deal with inheritance after an exec */
h = OpenFileMappingA (FILE_MAP_READ | FILE_MAP_WRITE, FALSE, mapname);
created = 0;
}
else
{
h = CreateFileMapping ((HANDLE) 0xffffffff, &sec_all_nih,
PAGE_READWRITE, 0, mapsize, mapname);
created = h && GetLastError () != ERROR_ALREADY_EXISTS;
}
if (procinfo->process_state & PID_EXECED) if (!h)
{ {
pid_t realpid = procinfo->pid; if (create)
debug_printf ("execed process windows pid %d, cygwin pid %d", n, realpid); __seterrno ();
release (); procinfo = NULL;
if (realpid == n) return;
api_fatal ("retrieval of execed process info for pid %d failed due to recursion.", n); }
return init (realpid);
}
if (created) procinfo = (_pinfo *) MapViewOfFile (h, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
{ ProtectHandle1 (h, pinfo_shared_handle);
if (!(create & PID_EXECED))
if (procinfo->process_state & PID_EXECED)
{
assert (!i);
pid_t realpid = procinfo->pid;
debug_printf ("execed process windows pid %d, cygwin pid %d", n, realpid);
if (realpid == n)
api_fatal ("retrieval of execed process info for pid %d failed due to recursion.", n);
n = realpid;
release ();
continue;
}
/* In certain rare, pathological cases, it is possible for the shared
memory region to exist for a while after a process has exited. This
should only be a brief occurrence, so rather than introduce some kind
of locking mechanism, just loop. FIXME: I'm sure I'll regret doing it
this way at some point. */
if (i < 9 && !created && create && (procinfo->process_state & PID_EXITED))
{
Sleep (5);
release ();
continue;
}
if (!created)
/* nothing */;
else if (!(create & PID_EXECED))
procinfo->pid = n; procinfo->pid = n;
else else
{ {
procinfo->pid = myself->pid; procinfo->pid = myself->pid;
procinfo->process_state |= PID_IN_USE | PID_EXECED; procinfo->process_state |= PID_IN_USE | PID_EXECED;
} }
break;
} }
destroy = 1; destroy = 1;
} }

View File

@ -94,6 +94,13 @@ public:
char root[MAX_PATH+1]; char root[MAX_PATH+1];
size_t rootlen; size_t rootlen;
/* Resources used by process. */
long start_time;
struct rusage rusage_self;
struct rusage rusage_children;
/* Pointer to mmap'ed areas for this process. Set up by fork. */
void *mmap_ptr;
/* Non-zero if process was stopped by a signal. */ /* Non-zero if process was stopped by a signal. */
char stopsig; char stopsig;
@ -104,21 +111,13 @@ public:
LONG* getsigtodo (int); LONG* getsigtodo (int);
HANDLE getthread2signal (); HANDLE getthread2signal ();
void setthread2signal (void *); void setthread2signal (void *);
void exit (UINT n) __attribute__ ((noreturn));
/* Resources used by process. */
long start_time;
struct rusage rusage_self;
struct rusage rusage_children;
private: private:
struct sigaction sigs[NSIG]; struct sigaction sigs[NSIG];
sigset_t sig_mask; /* one set for everything to ignore. */ sigset_t sig_mask; /* one set for everything to ignore. */
LONG _sigtodo[NSIG + __SIGOFFSET]; LONG _sigtodo[NSIG + __SIGOFFSET];
ThreadItem* thread2signal; // NULL means means thread any other means a pthread ThreadItem* thread2signal; // NULL means means thread any other means a pthread
public:
/* Pointer to mmap'ed areas for this process. Set up by fork. */
void *mmap_ptr;
}; };
class pinfo class pinfo
@ -128,7 +127,7 @@ class pinfo
int destroy; int destroy;
public: public:
void init (pid_t n, DWORD create = 0, HANDLE h = NULL); void init (pid_t n, DWORD create = 0, HANDLE h = NULL);
pinfo (): h (NULL), procinfo (0), destroy (0) {} pinfo () {}
pinfo (_pinfo *x): procinfo (x) {} pinfo (_pinfo *x): procinfo (x) {}
pinfo (pid_t n) {init (n);} pinfo (pid_t n) {init (n);}
pinfo (pid_t n, int create) {init (n, create);} pinfo (pid_t n, int create) {init (n, create);}
@ -181,7 +180,8 @@ extern pinfo myself;
extern "C" int _spawnve (HANDLE hToken, int mode, const char *path, extern "C" int _spawnve (HANDLE hToken, int mode, const char *path,
const char *const *argv, const char *const *envp); const char *const *argv, const char *const *envp);
extern void __stdcall exec_fixup_after_fork (); extern void __stdcall pinfo_fixup_after_fork ();
extern void __stdcall pinfo_fixup_in_spawned_child (HANDLE hchild);
/* For mmaps across fork(). */ /* For mmaps across fork(). */
int __stdcall recreate_mmaps_after_fork (void *); int __stdcall recreate_mmaps_after_fork (void *);

View File

@ -65,6 +65,7 @@ fill_rusage (struct rusage *r, HANDLE h)
struct timeval tv; struct timeval tv;
memset (r, 0, sizeof (*r));
GetProcessTimes (h, &creation_time, &exit_time, &kernel_time, &user_time); GetProcessTimes (h, &creation_time, &exit_time, &kernel_time, &user_time);
totimeval (&tv, &kernel_time, 0, 0); totimeval (&tv, &kernel_time, 0, 0);
add_timeval (&r->ru_stime, &tv); add_timeval (&r->ru_stime, &tv);

View File

@ -602,7 +602,6 @@ write_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size)
int int
set_process_privileges () set_process_privileges ()
{ {
HANDLE hProcess = NULL;
HANDLE hToken = NULL; HANDLE hToken = NULL;
LUID restore_priv; LUID restore_priv;
LUID backup_priv; LUID backup_priv;
@ -610,14 +609,7 @@ set_process_privileges ()
TOKEN_PRIVILEGES *new_priv = (TOKEN_PRIVILEGES *) buf; TOKEN_PRIVILEGES *new_priv = (TOKEN_PRIVILEGES *) buf;
int ret = -1; int ret = -1;
hProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId ()); if (! OpenProcessToken (hMainProc,
if (! hProcess)
{
__seterrno ();
goto out;
}
if (! OpenProcessToken (hProcess,
TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
&hToken)) &hToken))
{ {
@ -656,8 +648,6 @@ set_process_privileges ()
out: out:
if (hToken) if (hToken)
CloseHandle (hToken); CloseHandle (hToken);
if (hProcess)
CloseHandle (hProcess);
syscall_printf ("%d = set_process_privileges ()", ret); syscall_printf ("%d = set_process_privileges ()", ret);
return ret; return ret;

View File

@ -19,6 +19,10 @@ details. */
#include "sigproc.h" #include "sigproc.h"
#include "pinfo.h" #include "pinfo.h"
int sigcatchers; /* FIXME: Not thread safe. */
#define sigtrapped(func) ((func) != SIG_IGN && (func) != SIG_DFL)
extern "C" _sig_func_ptr extern "C" _sig_func_ptr
signal (int sig, _sig_func_ptr func) signal (int sig, _sig_func_ptr func)
{ {
@ -35,6 +39,11 @@ signal (int sig, _sig_func_ptr func)
prev = myself->getsig (sig).sa_handler; prev = myself->getsig (sig).sa_handler;
myself->getsig (sig).sa_handler = func; myself->getsig (sig).sa_handler = func;
myself->getsig (sig).sa_mask = 0; myself->getsig (sig).sa_mask = 0;
if (!sigtrapped (prev) && sigtrapped (func))
sigcatchers++;
else if (sigtrapped (prev) && !sigtrapped (func))
sigcatchers--;
syscall_printf ("%p = signal (%d, %p)", prev, sig, func); syscall_printf ("%p = signal (%d, %p)", prev, sig, func);
return prev; return prev;
} }
@ -224,12 +233,8 @@ killpg (int pgrp, int sig)
} }
extern "C" int extern "C" int
sigaction (int sig, sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact)
const struct sigaction *newaction,
struct sigaction *oldaction)
{ {
struct sigaction out_oldaction;
/* check that sig is in right range */ /* check that sig is in right range */
if (sig < 0 || sig >= NSIG) if (sig < 0 || sig >= NSIG)
{ {
@ -238,25 +243,28 @@ sigaction (int sig,
return -1; return -1;
} }
if (oldaction) struct sigaction oa = myself->getsig (sig);
out_oldaction = myself->getsig (sig);
if (newaction) if (newact)
{ {
if ((sig == SIGKILL || sig == SIGSTOP) && newaction->sa_handler != SIG_DFL) if ((sig == SIGKILL || sig == SIGSTOP) && newact->sa_handler != SIG_DFL)
{ {
set_errno (EINVAL); set_errno (EINVAL);
return -1; return -1;
} }
myself->getsig (sig) = *newaction; myself->getsig (sig) = *newact;
if (newaction->sa_handler == SIG_IGN) if (newact->sa_handler == SIG_IGN)
sig_clear (sig); sig_clear (sig);
if (newaction->sa_handler == SIG_DFL && sig == SIGCHLD) if (newact->sa_handler == SIG_DFL && sig == SIGCHLD)
sig_clear (sig); sig_clear (sig);
if (!sigtrapped (oa.sa_handler) && sigtrapped (newact->sa_handler))
sigcatchers++;
else if (sigtrapped (oa.sa_handler) && !sigtrapped (newact->sa_handler))
sigcatchers--;
} }
if (oldaction) if (oldact)
*oldaction = out_oldaction; *oldact = oa;
return 0; return 0;
} }

View File

@ -97,8 +97,8 @@ Static HANDLE wait_sig_inited = NULL; // Control synchronization of
*/ */
Static HANDLE events[PSIZE + 1] = {0}; // All my children's handles++ Static HANDLE events[PSIZE + 1] = {0}; // All my children's handles++
#define hchildren (events + 1) // Where the children handles begin #define hchildren (events + 1) // Where the children handles begin
Static pinfo pchildren[PSIZE] = {pinfo ()};// All my children info Static pinfo pchildren[PSIZE]; // All my children info
Static pinfo zombies[PSIZE] = {pinfo ()}; // All my deceased children info Static pinfo zombies[PSIZE]; // All my deceased children info
Static int nchildren = 0; // Number of active children Static int nchildren = 0; // Number of active children
Static int nzombies = 0; // Number of deceased children Static int nzombies = 0; // Number of deceased children
@ -195,18 +195,12 @@ pid_exists (pid_t pid)
return proc_exists (p); return proc_exists (p);
} }
/* Test to determine if a process really exists and is processing /* Test to determine if a process really exists and is processing signals.
* signals.
*/ */
BOOL __stdcall BOOL __stdcall
proc_exists (_pinfo *p) proc_exists (_pinfo *p)
{ {
HANDLE h; return p && !(p->process_state & (PID_INITIALIZING | PID_EXITED));
if (p == NULL)
return FALSE;
else
return TRUE;
} }
/* Return 1 if this is one of our children, zero otherwise. /* Return 1 if this is one of our children, zero otherwise.
@ -266,7 +260,7 @@ proc_subproc (DWORD what, DWORD val)
hchildren[nchildren] = vchild->hProcess; hchildren[nchildren] = vchild->hProcess;
ProtectHandle1 (vchild->hProcess, childhProc); ProtectHandle1 (vchild->hProcess, childhProc);
if (!DuplicateHandle (hMainProc, vchild->hProcess, hMainProc, &vchild->pid_handle, if (!DuplicateHandle (hMainProc, vchild->hProcess, hMainProc, &vchild->pid_handle,
0, 0, DUPLICATE_SAME_ACCESS)) 0, 0, DUPLICATE_SAME_ACCESS))
system_printf ("Couldn't duplicate child handle for pid %d, %E", vchild->pid); system_printf ("Couldn't duplicate child handle for pid %d, %E", vchild->pid);
ProtectHandle1 (vchild->pid_handle, pid_handle); ProtectHandle1 (vchild->pid_handle, pid_handle);
sigproc_printf ("added pid %d to wait list, slot %d, winpid %p, handle %p", sigproc_printf ("added pid %d to wait list, slot %d, winpid %p, handle %p",
@ -301,11 +295,6 @@ proc_subproc (DWORD what, DWORD val)
zombies[nzombies] = pchildren[val]; // Add to zombie array zombies[nzombies] = pchildren[val]; // Add to zombie array
zombies[nzombies++]->process_state = PID_ZOMBIE;// Walking dead zombies[nzombies++]->process_state = PID_ZOMBIE;// Walking dead
remove_child (val); // Remove from children array remove_child (val); // Remove from children array
if (!proc_loop_wait) // Don't bother if wait_subproc is
break; // exiting
/* Send a SIGCHLD to myself. */
rc = sig_send (myself_nowait, SIGCHLD); // Send a SIGCHLD
break; break;
/* A child is in the stopped state. Scan wait() queue to see if anyone /* A child is in the stopped state. Scan wait() queue to see if anyone
@ -445,15 +434,13 @@ proc_terminate (void)
ForceCloseHandle1 (zombies[i]->hProcess, childhProc); ForceCloseHandle1 (zombies[i]->hProcess, childhProc);
ForceCloseHandle1 (zombies[i]->pid_handle, pid_handle); ForceCloseHandle1 (zombies[i]->pid_handle, pid_handle);
} }
zombies[i]->process_state = PID_NOT_IN_USE; /* CGF FIXME - still needed? */ zombies[i]->process_state = PID_EXITED; /* CGF FIXME - still needed? */
zombies[i].release(); // FIXME: this breaks older gccs for some reason zombies[i].release(); // FIXME: this breaks older gccs for some reason
} }
/* Disassociate my subprocesses */ /* Disassociate my subprocesses */
for (i = 0; i < nchildren; i++) for (i = 0; i < nchildren; i++)
{ {
if (pchildren[i]->process_state == PID_NOT_IN_USE)
continue; // Should never happen
if (!pchildren[i]->hProcess) if (!pchildren[i]->hProcess)
sigproc_printf ("%d(%d) hProcess cleared already?", pchildren[i]->pid, sigproc_printf ("%d(%d) hProcess cleared already?", pchildren[i]->pid,
pchildren[i]->dwProcessId); pchildren[i]->dwProcessId);
@ -596,10 +583,10 @@ sigproc_terminate (void)
ForceCloseHandle (sigcomplete_main); ForceCloseHandle (sigcomplete_main);
for (int i = 0; i < 20; i++) for (int i = 0; i < 20; i++)
(void) ReleaseSemaphore (sigcomplete_nonmain, 1, NULL); (void) ReleaseSemaphore (sigcomplete_nonmain, 1, NULL);
ForceCloseHandle (sigcomplete_nonmain); // ForceCloseHandle (sigcomplete_nonmain);
ForceCloseHandle (sigcatch_main); // ForceCloseHandle (sigcatch_main);
ForceCloseHandle (sigcatch_nonmain); // ForceCloseHandle (sigcatch_nonmain);
ForceCloseHandle (sigcatch_nosync); // ForceCloseHandle (sigcatch_nosync);
} }
proc_terminate (); // Terminate process handling thread proc_terminate (); // Terminate process handling thread
@ -610,19 +597,19 @@ sigproc_terminate (void)
sigproc_printf ("entering"); sigproc_printf ("entering");
sig_loop_wait = 0; // Tell wait_sig to exit when it is sig_loop_wait = 0; // Tell wait_sig to exit when it is
// finished with anything it is doing // finished with anything it is doing
sig_dispatch_pending (TRUE); // wake up and die // sig_dispatch_pending (TRUE); // wake up and die
/* In case of a sigsuspend */
SetEvent (signal_arrived);
/* If !hwait_sig, then the process probably hasn't even finished /* If !hwait_sig, then the process probably hasn't even finished
* its initialization phase. * its initialization phase.
*/ */
if (hwait_sig) if (0 && hwait_sig)
{ {
if (GetCurrentThreadId () != sigtid) if (GetCurrentThreadId () != sigtid)
WaitForSingleObject (h, 10000); WaitForSingleObject (h, 10000);
ForceCloseHandle1 (h, hwait_sig); ForceCloseHandle1 (h, hwait_sig);
/* In case of a sigsuspend */
SetEvent (signal_arrived);
if (GetCurrentThreadId () != sigtid) if (GetCurrentThreadId () != sigtid)
{ {
@ -636,9 +623,11 @@ sigproc_terminate (void)
sigproc_printf ("done"); sigproc_printf ("done");
} }
#if 0
/* Set this so that subsequent tests will succeed. */ /* Set this so that subsequent tests will succeed. */
if (!myself->dwProcessId) if (!myself->dwProcessId)
myself->dwProcessId = GetCurrentProcessId (); myself->dwProcessId = GetCurrentProcessId ();
#endif
return; return;
} }
@ -1128,7 +1117,7 @@ wait_sig (VOID *)
* Signalling subproc_ready indicates that we are a cygwin process. * Signalling subproc_ready indicates that we are a cygwin process.
*/ */
if (child_proc_info && if (child_proc_info &&
(child_proc_info->type == PROC_FORK || child_proc_info->type == PROC_SPAWN)) (child_proc_info->type == PROC_EXEC || child_proc_info->type == PROC_SPAWN))
{ {
debug_printf ("subproc_ready %p", child_proc_info->subproc_ready); debug_printf ("subproc_ready %p", child_proc_info->subproc_ready);
if (!SetEvent (child_proc_info->subproc_ready)) if (!SetEvent (child_proc_info->subproc_ready))
@ -1144,13 +1133,6 @@ wait_sig (VOID *)
SetEvent (wait_sig_inited); SetEvent (wait_sig_inited);
sigtid = GetCurrentThreadId (); sigtid = GetCurrentThreadId ();
/* If we got something like a SIGINT while we were initializing, the
signal thread should be waiting for this event. This signals the
thread that it's ok to send the signal since the wait_sig thread
is now active. */
extern HANDLE console_handler_thread_waiter;
SetEvent (console_handler_thread_waiter);
HANDLE catchem[] = {sigcatch_main, sigcatch_nonmain, sigcatch_nosync}; HANDLE catchem[] = {sigcatch_main, sigcatch_nonmain, sigcatch_nosync};
sigproc_printf ("Ready. dwProcessid %d", myself->dwProcessId); sigproc_printf ("Ready. dwProcessid %d", myself->dwProcessId);
for (;;) for (;;)
@ -1306,7 +1288,14 @@ wait_subproc (VOID *)
errloop = 0; errloop = 0;
rc -= WAIT_OBJECT_0; rc -= WAIT_OBJECT_0;
if (rc-- != 0) if (rc-- != 0)
(void)proc_subproc (PROC_CHILDTERMINATED, rc); {
(void) proc_subproc (PROC_CHILDTERMINATED, rc);
if (!proc_loop_wait) // Don't bother if wait_subproc is
break; // exiting
/* Send a SIGCHLD to myself. */
rc = sig_send (myself_nowait, SIGCHLD);
}
sigproc_printf ("looping"); sigproc_printf ("looping");
} }
@ -1327,7 +1316,6 @@ WFSO (HANDLE hHandle, DWORD dwMilliseconds)
DWORD ret; DWORD ret;
sigframe thisframe (mainthread); sigframe thisframe (mainthread);
ret = WaitForSingleObject (hHandle, dwMilliseconds); ret = WaitForSingleObject (hHandle, dwMilliseconds);
if (dwMilliseconds > 10 && ret == WAIT_TIMEOUT) system_printf ("TIMED OUT %d\n", dwMilliseconds);
return ret; return ret;
} }
@ -1339,7 +1327,6 @@ WFMO (DWORD nCount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds
DWORD ret; DWORD ret;
sigframe thisframe (mainthread); sigframe thisframe (mainthread);
ret = WaitForMultipleObjects (nCount, lpHandles, fWaitAll, dwMilliseconds); ret = WaitForMultipleObjects (nCount, lpHandles, fWaitAll, dwMilliseconds);
if (dwMilliseconds > 10 && ret == WAIT_TIMEOUT) system_printf ("TIMED OUT %d\n", dwMilliseconds);
return ret; return ret;
} }
} }

View File

@ -39,7 +39,6 @@ struct sigthread
DWORD id; DWORD id;
DWORD frame; DWORD frame;
muto *lock; muto *lock;
sigthread () : id (0), frame (0), lock (0) {}
void init (const char *s); void init (const char *s);
}; };

View File

@ -219,16 +219,6 @@ linebuf::prepend (const char *what, int len)
ix = newix; ix = newix;
} }
static HANDLE hexec_proc = NULL;
void __stdcall
exec_fixup_after_fork ()
{
if (hexec_proc)
CloseHandle (hexec_proc);
hexec_proc = NULL;
}
class av class av
{ {
char **argv; char **argv;
@ -351,7 +341,7 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
} }
ciresrv.moreinfo = (cygheap_exec_info *) ccalloc (HEAP_1_EXEC, 1, sizeof (cygheap_exec_info)); ciresrv.moreinfo = (cygheap_exec_info *) ccalloc (HEAP_1_EXEC, 1, sizeof (cygheap_exec_info));
ciresrv.moreinfo->old_title = old_title ? cstrdup (old_title) : NULL; ciresrv.moreinfo->old_title = NULL;
ciresrv.moreinfo->fds = fdtab; ciresrv.moreinfo->fds = fdtab;
ciresrv.moreinfo->nfds = fdtab.size; ciresrv.moreinfo->nfds = fdtab.size;
@ -562,14 +552,6 @@ skip_arg_parsing:
if (!hToken && myself->token != INVALID_HANDLE_VALUE) if (!hToken && myself->token != INVALID_HANDLE_VALUE)
hToken = myself->token; hToken = myself->token;
/* FIXME: This leaves a handle to the process open so that the pid is not
duplicated. However, if a process execs another process two handles are
left open, which is unnecessary. */
if (mode == _P_OVERLAY && !hexec_proc &&
!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hexec_proc, 0,
TRUE, DUPLICATE_SAME_ACCESS))
system_printf ("couldn't save current process handle %p, %E", hMainProc);
if (hToken) if (hToken)
{ {
/* allow the child to interact with our window station/desktop */ /* allow the child to interact with our window station/desktop */
@ -631,18 +613,18 @@ skip_arg_parsing:
seteuid (uid); seteuid (uid);
} }
else else
rc = CreateProcessA (real_path, /* image name - with full path */ rc = CreateProcess (real_path, /* image name - with full path */
one_line.buf, /* what was passed to exec */ one_line.buf, /* what was passed to exec */
/* process security attrs */ /* process security attrs */
allow_ntsec ? sec_user (sa_buf) : &sec_all_nih, allow_ntsec ? sec_user (sa_buf) : &sec_all_nih,
/* thread security attrs */ /* thread security attrs */
allow_ntsec ? sec_user (sa_buf) : &sec_all_nih, allow_ntsec ? sec_user (sa_buf) : &sec_all_nih,
TRUE, /* inherit handles from parent */ TRUE, /* inherit handles from parent */
flags, flags,
envblock,/* environment */ envblock,/* environment */
0, /* use current drive/directory */ 0, /* use current drive/directory */
&si, &si,
&pi); &pi);
MALLOC_CHECK; MALLOC_CHECK;
if (envblock) if (envblock)
@ -691,6 +673,7 @@ skip_arg_parsing:
} }
else else
{ {
pinfo_fixup_in_spawned_child (pi.hProcess);
pinfo child (cygpid, 1); pinfo child (cygpid, 1);
if (!child) if (!child)
{ {
@ -859,6 +842,9 @@ skip_arg_parsing:
{ {
case _P_OVERLAY: case _P_OVERLAY:
proc_terminate (); proc_terminate ();
struct rusage r;
fill_rusage (&r, hMainProc);
add_rusage (&myself->rusage_self, &r);
ExitProcess (0); ExitProcess (0);
break; break;
case _P_WAIT: case _P_WAIT:

View File

@ -27,10 +27,8 @@ public:
void operator delete (void *) {;} /* can't handle allocated mutos void operator delete (void *) {;} /* can't handle allocated mutos
currently */ currently */
/* This simple constructor is used for cases where no bruteforce muto() {}
event handling is required. */ /* The real constructor. */
muto(): sync(0), visits(0), waiters(-1), bruteforce(0), tid(0), next (NULL) {;}
/* A more complicated constructor. */
muto(int inh, const char *name); muto(int inh, const char *name);
~muto (); ~muto ();
int acquire (DWORD ms = INFINITE); /* Acquire the lock. */ int acquire (DWORD ms = INFINITE); /* Acquire the lock. */

View File

@ -53,10 +53,16 @@ extern BOOL allow_ntsec;
void __stdcall void __stdcall
close_all_files (void) close_all_files (void)
{ {
for (int i = 0; i < (int)fdtab.size; i++) SetResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK," close");
if (!fdtab.not_open (i))
_close (i);
for (int i = 0; i < (int) fdtab.size; i++)
if (!fdtab.not_open (i))
{
fdtab[i]->close ();
fdtab.release (i);
}
ReleaseResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK," close");
cygwin_shared->delqueue.process_queue (); cygwin_shared->delqueue.process_queue ();
} }
@ -200,6 +206,7 @@ extern "C" int
_read (int fd, void *ptr, size_t len) _read (int fd, void *ptr, size_t len)
{ {
sigframe thisframe (mainthread); sigframe thisframe (mainthread);
extern int sigcatchers;
if (fdtab.not_open (fd)) if (fdtab.not_open (fd))
{ {
set_errno (EBADF); set_errno (EBADF);
@ -211,10 +218,10 @@ _read (int fd, void *ptr, size_t len)
DWORD wait = (fh->get_flags () & (O_NONBLOCK | OLD_O_NDELAY)) ? 0 : INFINITE; DWORD wait = (fh->get_flags () & (O_NONBLOCK | OLD_O_NDELAY)) ? 0 : INFINITE;
/* Could block, so let user know we at least got here. */ /* Could block, so let user know we at least got here. */
syscall_printf ("read (%d, %p, %d) %sblocking", fd, ptr, len, wait ? "" : "non"); syscall_printf ("read (%d, %p, %d) %sblocking, sigcatchers %d", fd, ptr, len, wait ? "" : "non", sigcatchers);
int res; int res;
if (wait && (!fh->is_slow () || fh->get_r_no_interrupt ())) if (wait && (!sigcatchers || !fh->is_slow () || fh->get_r_no_interrupt ()))
debug_printf ("non-interruptible read\n"); debug_printf ("non-interruptible read\n");
else if (!fh->ready_for_read (fd, wait, 0)) else if (!fh->ready_for_read (fd, wait, 0))
{ {
@ -236,7 +243,6 @@ _read (int fd, void *ptr, size_t len)
myself->process_state &= ~PID_TTYIN; myself->process_state &= ~PID_TTYIN;
} }
out: out:
syscall_printf ("%d = read (%d<%s>, %p, %d), errno %d", res, fd, fh->get_name (), syscall_printf ("%d = read (%d<%s>, %p, %d), errno %d", res, fd, fh->get_name (),
ptr, len, get_errno ()); ptr, len, get_errno ());
@ -988,7 +994,7 @@ suffix_info stat_suffixes[] =
/* Cygwin internal */ /* Cygwin internal */
static int static int
stat_worker (const char *caller, const char *name, struct stat *buf, stat_worker (const char *caller, const char *name, struct stat *buf,
int nofollow) int nofollow)
{ {
int res = -1; int res = -1;
int oret = 1; int oret = 1;

View File

@ -29,7 +29,7 @@ extern "C"
#if defined (_CYG_THREAD_FAILSAFE) && defined (_MT_SAFE) #if defined (_CYG_THREAD_FAILSAFE) && defined (_MT_SAFE)
void AssertResourceOwner (int, int); void AssertResourceOwner (int, int);
#else #else
#define AssertResourceOwner(i,ii) # define AssertResourceOwner(i,ii)
#endif #endif
} }
@ -126,17 +126,17 @@ class pinfo;
class ResourceLocks class ResourceLocks
{ {
public: public:
ResourceLocks ():inited (false) {}; ResourceLocks () {};
LPCRITICAL_SECTION Lock (int); LPCRITICAL_SECTION Lock (int);
void Init (); void Init ();
void Delete (); void Delete ();
#ifdef _CYG_THREAD_FAILSAFE #ifdef _CYG_THREAD_FAILSAFE
DWORD owner; DWORD owner;
DWORD count; DWORD count;
#endif #endif
private: private:
CRITICAL_SECTION lock; CRITICAL_SECTION lock;
bool inited; bool inited;
}; };
@ -146,100 +146,99 @@ bool inited;
class MTitem class MTitem
{ {
public: public:
HANDLE win32_obj_id; HANDLE win32_obj_id;
UINT return_value; UINT return_value;
bool used; bool used;
char joinable; // for thread only char joinable; // for thread only
bool HandleOke () {return win32_obj_id;} bool HandleOke () {return win32_obj_id;}
virtual void Destroy (); virtual void Destroy ();
virtual int Id () {return (int) win32_obj_id;} virtual int Id () {return (int) win32_obj_id;}
}; };
class ThreadItem:public MTitem class ThreadItem: public MTitem
{ {
public: public:
pthread_attr_t attr; pthread_attr_t attr;
TFD (function); TFD (function);
void *arg; void *arg;
void *return_ptr; void *return_ptr;
bool suspended; bool suspended;
DWORD thread_id; DWORD thread_id;
DWORD GetThreadId () {return thread_id;} DWORD GetThreadId () {return thread_id;}
/* signal handling */ /* signal handling */
struct sigaction *sigs; struct sigaction *sigs;
sigset_t *sigmask; sigset_t *sigmask;
LONG *sigtodo; LONG *sigtodo;
}; };
class MutexItem:public MTitem class MutexItem: public MTitem
{ {
public: public:
int Lock (); int Lock ();
int TryLock (); int TryLock ();
int UnLock (); int UnLock ();
}; };
class SemaphoreItem:public MTitem class SemaphoreItem: public MTitem
{ {
public: public:
int shared; int shared;
int Wait (); int Wait ();
int Post (); int Post ();
int TryWait (); int TryWait ();
}; };
typedef struct typedef struct
{ {
MTitem *items[MT_MAX_ITEMS]; MTitem *items[MT_MAX_ITEMS];
int index; int index;
} } MTList;
MTList;
class MTinterface class MTinterface
{ {
public: public:
// General // General
DWORD reent_index; DWORD reent_index;
DWORD thread_key; DWORD thread_key;
// Used for main thread data, and sigproc thread // Used for main thread data, and sigproc thread
struct __reent_t reents; struct __reent_t reents;
struct _winsup_t winsup_reent; struct _winsup_t winsup_reent;
ThreadItem mainthread; ThreadItem mainthread;
void Init0 (); void Init0 ();
void Init1 (); void Init1 ();
void ClearReent (); void ClearReent ();
void ReleaseItem (MTitem *); void ReleaseItem (MTitem *);
// Thread functions // Thread functions
ThreadItem *CreateThread (pthread_t *, TFD (func), void *, pthread_attr_t); ThreadItem *CreateThread (pthread_t *, TFD (func), void *, pthread_attr_t);
ThreadItem *GetCallingThread (); ThreadItem *GetCallingThread ();
ThreadItem *GetThread (pthread_t *); ThreadItem *GetThread (pthread_t *);
// Mutex functions // Mutex functions
MutexItem *CreateMutex (pthread_mutex_t *); MutexItem *CreateMutex (pthread_mutex_t *);
MutexItem *GetMutex (pthread_mutex_t *); MutexItem *GetMutex (pthread_mutex_t *);
// Semaphore functions // Semaphore functions
SemaphoreItem *CreateSemaphore (sem_t *, int, int); SemaphoreItem *CreateSemaphore (sem_t *, int, int);
SemaphoreItem *GetSemaphore (sem_t * t); SemaphoreItem *GetSemaphore (sem_t * t);
private: private:
// General Administration // General Administration
MTitem * Find (void *, int (*compare) (void *, void *), int &, MTList *); MTitem * Find (void *, int (*compare) (void *, void *), int &, MTList *);
MTitem *GetItem (int, MTList *); MTitem *GetItem (int, MTList *);
MTitem *SetItem (int, MTitem *, MTList *); MTitem *SetItem (int, MTitem *, MTList *);
int Find (MTitem &, MTList *); int Find (MTitem &, MTList *);
int FindNextUnused (MTList *); int FindNextUnused (MTList *);
MTList threadlist; MTList threadlist;
MTList mutexlist; MTList mutexlist;
MTList semalist; MTList semalist;
}; };