* spinlock.h: New file.

(spinlock): New class.
* shared.cc: Include spinlock.h.
(memory_init): Use new spinlock methods rather than roll-your-own.  Time out
after ten seconds if shared_mem_inited is not initialized.
* sync.h: Update copyright.  Remove vanity attribution.
* sigproc.cc (sigproc_terminate): Avoid attempts to kill the signal thread
while we're still initializing or suffer a deadlock.
This commit is contained in:
Christopher Faylor 2010-03-13 19:34:35 +00:00
parent 084ea5108e
commit f8af64be87
5 changed files with 78 additions and 36 deletions

View File

@ -1,3 +1,16 @@
2010-03-13 Christopher Faylor <me+cygwin@cgf.cx>
* spinlock.h: New file.
(spinlock): New class.
* shared.cc: Include spinlock.h.
(memory_init): Use new spinlock methods rather than roll-your-own.
Time out after ten seconds if shared_mem_inited is not initialized.
* sync.h: Update copyright. Remove vanity attribution.
* sigproc.cc (sigproc_terminate): Avoid attempts to kill the signal
thread while we're still initializing or suffer a deadlock.
2010-03-12 Christopher Faylor <me+cygwin@cgf.cx> 2010-03-12 Christopher Faylor <me+cygwin@cgf.cx>
Throughout change all calls of low_priority_sleep (0) to yield (). Throughout change all calls of low_priority_sleep (0) to yield ().

View File

@ -23,6 +23,7 @@ details. */
#include "registry.h" #include "registry.h"
#include "cygwin_version.h" #include "cygwin_version.h"
#include "pwdgrp.h" #include "pwdgrp.h"
#include "spinlock.h"
#include "ntdll.h" #include "ntdll.h"
#include <alloca.h> #include <alloca.h>
#include <wchar.h> #include <wchar.h>
@ -418,40 +419,28 @@ memory_init (bool init_cygheap)
} }
/* Initialize general shared memory under spinlock control */ /* Initialize general shared memory under spinlock control */
for (;;) {
{ spinlock smi (shared_mem_inited, 10000);
LONG smi = InterlockedExchange (&shared_mem_inited, -1); if (!smi)
if (smi < 0) init_installation_root (); /* Initialize installation root dir */
{
yield ();
continue;
}
if (!smi) cygwin_shared = (shared_info *) open_shared (L"shared",
/* Initialize installation root dir */ CYGWIN_VERSION_SHARED_DATA,
init_installation_root (); cygwin_shared_h,
sizeof (*cygwin_shared),
SH_CYGWIN_SHARED);
heap_init ();
cygwin_shared = (shared_info *) open_shared (L"shared", if (!smi)
CYGWIN_VERSION_SHARED_DATA, {
cygwin_shared_h, cygwin_shared->initialize ();
sizeof (*cygwin_shared), /* Defer debug output printing the installation root and installation key
SH_CYGWIN_SHARED); up to this point. Debug output except for system_printf requires
heap_init (); the global shared memory to exist. */
debug_printf ("Installation root: <%W> key: <%S>",
if (!smi) installation_root, &installation_key);
{ }
cygwin_shared->initialize (); }
/* Defer debug output printing the installation root and installation key
up to this point. Debug output except for system_printf requires
the global shared memory to exist. */
debug_printf ("Installation root: <%W> key: <%S>",
installation_root, &installation_key);
smi = 1;
}
InterlockedExchange (&shared_mem_inited, smi);
break;
}
user_shared_create (false); user_shared_create (false);
} }

View File

@ -494,7 +494,9 @@ sigproc_terminate (exit_states es)
{ {
exit_states prior_exit_state = exit_state; exit_states prior_exit_state = exit_state;
exit_state = es; exit_state = es;
if (prior_exit_state >= ES_FINAL) if (!cygwin_finished_initializing)
sigproc_printf ("don't worry about signal thread");
else if (prior_exit_state >= ES_FINAL)
sigproc_printf ("already performed"); sigproc_printf ("already performed");
else else
{ {

40
winsup/cygwin/spinlock.h Normal file
View File

@ -0,0 +1,40 @@
/* spinlock.h: Header file for cygwin time-sensitive synchronization primitive.
Copyright 2010 Red Hat, Inc.
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#ifndef _SPINLOCK_H
#define _SPINLOCK_H
#include "hires.h"
class spinlock
{
LONG *locker;
LONG val;
public:
spinlock (LONG& locktest, LONGLONG timeout):
locker (&locktest)
{
if ((val = locktest) == 1)
return;
LONGLONG then = gtod.msecs ();
for (;;)
{
if ((val = InterlockedExchange (locker, -1)) != -1
|| (gtod.msecs () - then) >= timeout)
break;
yield ();
}
}
~spinlock () {InterlockedExchange (locker, 1);}
operator LONG () const {return val;}
};
#endif /*_SPINLOCK_H*/

View File

@ -1,8 +1,6 @@
/* sync.h: Header file for cygwin synchronization primitives. /* sync.h: Header file for cygwin synchronization primitives.
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc.
Written by Christopher Faylor <cgf@cygnus.com>
This file is part of Cygwin. This file is part of Cygwin.