* shared_info.h (user_info): Add dll_crt0_1 as a friend.

(user_info::version): Make LONG to accommodate spinlock use.
(user_info::create): New static function renamed from user_info_create.
(user_info::initialize): New private function renamed from
user_info_initialize.
(SHARED_VERSION): Delete.
(SHARED_VERSION_MAGIC): Ditto.
(USER_VERSION_MAGIC): Ditto.
(SHARED_INFO_CB): Ditto.
(USER_VERSION): Ditto.
(USER_VERSION_MAGIC): Ditto.
(CURR_SHARED_MAGIC): Update.
(CURR_USER_MAGIC): Ditto.
(shared_info::version): Make LONG to accommodate spinlock use.
(shared_info::create): New static function mirroring user_info::create.
(dll_crt0_1): Accommodate change to user_info::initialize.
* spinlock.h (spinlock::setto): New variable member.
(spinlock::done): New function.
(spinlock::spinlock): Generalize to allow arbitrary values and timeouts.  Call
done() when lock is not needed.
* ntdll.h: Make multiple-inclusion safe.
(NtQuerySystemTime): Declare.
* shared.cc (installation_root_inited): Rename from shared_mem_inited.
(init_installation_root): Make inline.  Use a spinlock to ensure that this is
initialized only once per session.
(user_info::initialize): Rename from user_shared_initialize.  Protect with
spinlock on sversion and remove other spinlock-like things.  Remove reference
to user_shared since it is now implicit.  Refer to spinlock version of
multiple_cygwin_problem to ensure that any spinlock is released.
(user_info::create): Rename from user_shared_create.  Accommodate change from
user_shared_initialize to user_info::initialize.
(shared_info::create): New inline function.
(shared_info::initialize): Protect with spinlock on sversion.  Move heap_init
back under specific control of shared_info spinlock.  Remove reference to
SHARED_INFO_CB and just use sizeof(*this).
(memory_init): Move all locking into respective functions where it is needed.
Accommodate name changes.  Remove call to heap_init().
* syscalls.cc (seteuid32): Accommodate name change to user_info::create().
* mount.cc (mount_info::create_root_entry): Report on errors from add_item
since they should be nonexistent.
(mount_info::init): Don't initialize nmounts.  It should already be zero.  Give
more verbose error when root_idx < 0.  Implicitly use this pointer rather than
explicitly referencing mount_table->.
(mount_info::add_item): Minor whitespace fix.
This commit is contained in:
Christopher Faylor 2010-03-15 21:29:15 +00:00
parent 654e623ce0
commit cef5dfd75a
8 changed files with 219 additions and 129 deletions

View File

@ -1,3 +1,53 @@
2010-03-15 Christopher Faylor <me+cygwin@cgf.cx>
* shared_info.h (user_info): Add dll_crt0_1 as a friend.
(user_info::version): Make LONG to accommodate spinlock use.
(user_info::create): New static function renamed from user_info_create.
(user_info::initialize): New private function renamed from
user_info_initialize.
(SHARED_VERSION): Delete.
(SHARED_VERSION_MAGIC): Ditto.
(USER_VERSION_MAGIC): Ditto.
(SHARED_INFO_CB): Ditto.
(USER_VERSION): Ditto.
(USER_VERSION_MAGIC): Ditto.
(CURR_SHARED_MAGIC): Update.
(CURR_USER_MAGIC): Ditto.
(shared_info::version): Make LONG to accommodate spinlock use.
(shared_info::create): New static function mirroring user_info::create.
(dll_crt0_1): Accommodate change to user_info::initialize.
* spinlock.h (spinlock::setto): New variable member.
(spinlock::done): New function.
(spinlock::spinlock): Generalize to allow arbitrary values and
timeouts. Call done() when lock is not needed.
* ntdll.h: Make multiple-inclusion safe.
(NtQuerySystemTime): Declare.
* shared.cc (installation_root_inited): Rename from shared_mem_inited.
(init_installation_root): Make inline. Use a spinlock to ensure that
this is initialized only once per session.
(user_info::initialize): Rename from user_shared_initialize. Protect
with spinlock on sversion and remove other spinlock-like things.
Remove reference to user_shared since it is now implicit. Refer to
spinlock version of multiple_cygwin_problem to ensure that any spinlock
is released.
(user_info::create): Rename from user_shared_create. Accommodate
change from user_shared_initialize to user_info::initialize.
(shared_info::create): New inline function.
(shared_info::initialize): Protect with spinlock on sversion. Move
heap_init back under specific control of shared_info spinlock. Remove
reference to SHARED_INFO_CB and just use sizeof(*this).
(memory_init): Move all locking into respective functions where it is
needed. Accommodate name changes. Remove call to heap_init().
* syscalls.cc (seteuid32): Accommodate name change to
user_info::create().
* mount.cc (mount_info::create_root_entry): Report on errors from
add_item since they should be nonexistent.
(mount_info::init): Don't initialize nmounts. It should already be
zero. Give more verbose error when root_idx < 0. Implicitly use this
pointer rather than explicitly referencing mount_table->.
(mount_info::add_item): Minor whitespace fix.
2010-03-15 Christopher Faylor <me+cygwin@cgf.cx> 2010-03-15 Christopher Faylor <me+cygwin@cgf.cx>
* sigproc.cc (no_signals_available): Get sense of the test right for * sigproc.cc (no_signals_available): Get sense of the test right for

View File

@ -778,7 +778,7 @@ dll_crt0_1 (void *)
have overridden malloc. We only know about that at this stage, have overridden malloc. We only know about that at this stage,
unfortunately. */ unfortunately. */
malloc_init (); malloc_init ();
user_shared_initialize (); user_shared->initialize ();
#ifdef CGF #ifdef CGF
int i = 0; int i = 0;

View File

@ -338,8 +338,11 @@ mount_info::create_root_entry (const PWCHAR root)
The entry is immutable, unless the "override" option is given in /etc/fstab. */ The entry is immutable, unless the "override" option is given in /etc/fstab. */
char native_root[PATH_MAX]; char native_root[PATH_MAX];
sys_wcstombs (native_root, PATH_MAX, root); sys_wcstombs (native_root, PATH_MAX, root);
mount_table->add_item (native_root, "/", assert (*native_root != '\0');
MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_IMMUTABLE | MOUNT_AUTOMATIC); if (add_item (native_root, "/",
MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_IMMUTABLE | MOUNT_AUTOMATIC)
< 0)
api_fatal ("add_item (\"%W\", \"/\", ...) failed, errno %d", native_root, errno);
/* Create a default cygdrive entry. Note that this is a user entry. /* Create a default cygdrive entry. Note that this is a user entry.
This allows to override it with mount, unless the sysadmin created This allows to override it with mount, unless the sysadmin created
a cygdrive entry in /etc/fstab. */ a cygdrive entry in /etc/fstab. */
@ -353,7 +356,6 @@ mount_info::create_root_entry (const PWCHAR root)
void void
mount_info::init () mount_info::init ()
{ {
nmounts = 0;
PWCHAR pathend; PWCHAR pathend;
WCHAR path[PATH_MAX]; WCHAR path[PATH_MAX];
@ -367,18 +369,19 @@ mount_info::init ()
if (!got_usr_bin || !got_usr_lib) if (!got_usr_bin || !got_usr_lib)
{ {
char native[PATH_MAX]; char native[PATH_MAX];
assert (root_idx != -1); if (root_idx < 0)
api_fatal ("root_idx %d, user_shared magic %p, nmounts %d", root_idx, user_shared->version, nmounts);
char *p = stpcpy (native, mount[root_idx].native_path); char *p = stpcpy (native, mount[root_idx].native_path);
if (!got_usr_bin) if (!got_usr_bin)
{ {
stpcpy (p, "\\bin"); stpcpy (p, "\\bin");
mount_table->add_item (native, "/usr/bin", add_item (native, "/usr/bin",
MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_AUTOMATIC); MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_AUTOMATIC);
} }
if (!got_usr_lib) if (!got_usr_lib)
{ {
stpcpy (p, "\\lib"); stpcpy (p, "\\lib");
mount_table->add_item (native, "/usr/lib", add_item (native, "/usr/lib",
MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_AUTOMATIC); MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_AUTOMATIC);
} }
} }
@ -1285,7 +1288,7 @@ mount_info::add_item (const char *native, const char *posix,
if (nativeerr || posixerr) if (nativeerr || posixerr)
{ {
set_errno (nativeerr?:posixerr); set_errno (nativeerr ?: posixerr);
return -1; return -1;
} }

View File

@ -9,6 +9,8 @@
Cygwin license. Please consult the file "CYGWIN_LICENSE" for Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */ details. */
#ifndef _NTDLL_H
#define _NTDLL_H 1
#define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS) 0x00000106) #define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS) 0x00000106)
#define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS) 0x40000000) #define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS) 0x40000000)
#define STATUS_BUFFER_OVERFLOW ((NTSTATUS) 0x80000005) #define STATUS_BUFFER_OVERFLOW ((NTSTATUS) 0x80000005)
@ -937,6 +939,9 @@ extern "C"
ULONG, ULONG *); ULONG, ULONG *);
NTSTATUS NTAPI NtQuerySystemInformation (SYSTEM_INFORMATION_CLASS, NTSTATUS NTAPI NtQuerySystemInformation (SYSTEM_INFORMATION_CLASS,
PVOID, ULONG, PULONG); PVOID, ULONG, PULONG);
NTSTATUS WINAPI NtQuerySystemTime (PLARGE_INTEGER);
NTSTATUS NTAPI NtQuerySecurityObject (HANDLE, SECURITY_INFORMATION, NTSTATUS NTAPI NtQuerySecurityObject (HANDLE, SECURITY_INFORMATION,
PSECURITY_DESCRIPTOR, ULONG, PULONG); PSECURITY_DESCRIPTOR, ULONG, PULONG);
NTSTATUS NTAPI NtQueryVirtualMemory (HANDLE, PVOID, MEMORY_INFORMATION_CLASS, NTSTATUS NTAPI NtQueryVirtualMemory (HANDLE, PVOID, MEMORY_INFORMATION_CLASS,
@ -1094,3 +1099,4 @@ extern "C"
return NtSetInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation); return NtSetInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
} }
} }
#endif /*_NTDLL_H*/

View File

@ -24,7 +24,6 @@ details. */
#include "cygwin_version.h" #include "cygwin_version.h"
#include "pwdgrp.h" #include "pwdgrp.h"
#include "spinlock.h" #include "spinlock.h"
#include "ntdll.h"
#include <alloca.h> #include <alloca.h>
#include <wchar.h> #include <wchar.h>
#include <wingdi.h> #include <wingdi.h>
@ -38,7 +37,9 @@ HANDLE NO_COPY cygwin_user_h;
WCHAR installation_root[PATH_MAX] __attribute__((section (".cygwin_dll_common"), shared)); WCHAR installation_root[PATH_MAX] __attribute__((section (".cygwin_dll_common"), shared));
UNICODE_STRING installation_key __attribute__((section (".cygwin_dll_common"), shared)); UNICODE_STRING installation_key __attribute__((section (".cygwin_dll_common"), shared));
WCHAR installation_key_buf[18] __attribute__((section (".cygwin_dll_common"), shared)); WCHAR installation_key_buf[18] __attribute__((section (".cygwin_dll_common"), shared));
static LONG shared_mem_inited __attribute__((section (".cygwin_dll_common"), shared)); static LONG installation_root_inited __attribute__((section (".cygwin_dll_common"), shared));
#define SPIN_WAIT 10000
/* Use absolute path of cygwin1.dll to derive the Win32 dir which /* Use absolute path of cygwin1.dll to derive the Win32 dir which
is our installation_root. Note that we can't handle Cygwin installation is our installation_root. Note that we can't handle Cygwin installation
@ -63,9 +64,11 @@ static LONG shared_mem_inited __attribute__((section (".cygwin_dll_common"), sha
multiple Cygwin DLLs, which we're just not aware of right now. Cygcheck multiple Cygwin DLLs, which we're just not aware of right now. Cygcheck
can be used to change the value in an existing Cygwin DLL binary. */ can be used to change the value in an existing Cygwin DLL binary. */
void void inline
init_installation_root () init_installation_root ()
{ {
if (!spinlock (installation_root_inited))
{
if (!GetModuleFileNameW (cygwin_hmodule, installation_root, PATH_MAX)) if (!GetModuleFileNameW (cygwin_hmodule, installation_root, PATH_MAX))
api_fatal ("Can't initialize Cygwin installation root dir.\n" api_fatal ("Can't initialize Cygwin installation root dir.\n"
"GetModuleFileNameW(%p, %p, %u), %E", "GetModuleFileNameW(%p, %p, %u), %E",
@ -116,6 +119,7 @@ init_installation_root ()
installation_key.Length = 0; installation_key.Length = 0;
installation_key.Buffer[0] = L'\0'; installation_key.Buffer[0] = L'\0';
} }
}
} }
/* This function returns a handle to the top-level directory in the global /* This function returns a handle to the top-level directory in the global
@ -301,35 +305,32 @@ open_shared (const WCHAR *name, int n, HANDLE& shared_h, DWORD size,
/* Second half of user shared initialization: Initialize content. */ /* Second half of user shared initialization: Initialize content. */
void void
user_shared_initialize () user_info::initialize ()
{ {
DWORD sversion = (DWORD) InterlockedExchange ((LONG *) &user_shared->version, USER_VERSION_MAGIC);
/* Wait for initialization of the Cygwin per-user shared, if necessary */ /* Wait for initialization of the Cygwin per-user shared, if necessary */
spinlock sversion (version, CURR_USER_MAGIC);
if (!sversion) if (!sversion)
{ {
cb = sizeof (*user_shared);
cygpsid sid (cygheap->user.sid ()); cygpsid sid (cygheap->user.sid ());
struct passwd *pw = internal_getpwsid (sid); struct passwd *pw = internal_getpwsid (sid);
/* Correct the user name with what's defined in /etc/passwd before /* Correct the user name with what's defined in /etc/passwd before
loading the user fstab file. */ loading the user fstab file. */
if (pw) if (pw)
cygheap->user.set_name (pw->pw_name); cygheap->user.set_name (pw->pw_name);
user_shared->mountinfo.init (); /* Initialize the mount table. */ mountinfo.init (); /* Initialize the mount table. */
user_shared->cb = sizeof (*user_shared);
} }
else else if (sversion != CURR_USER_MAGIC)
{ sversion.multiple_cygwin_problem ("user shared memory version", version,
while (!user_shared->cb) sversion);
yield (); // Should be hit only very very rarely
if (user_shared->version != sversion)
multiple_cygwin_problem ("user shared memory version", user_shared->version, sversion);
else if (user_shared->cb != sizeof (*user_shared)) else if (user_shared->cb != sizeof (*user_shared))
multiple_cygwin_problem ("user shared memory size", user_shared->cb, sizeof (*user_shared)); sversion.multiple_cygwin_problem ("user shared memory size", cb,
} sizeof (*user_shared));
} }
/* First half of user shared initialization: Create shared mem region. */ /* First half of user shared initialization: Create shared mem region. */
void void
user_shared_create (bool reinit) user_info::create (bool reinit)
{ {
WCHAR name[UNLEN + 1] = L""; /* Large enough for SID */ WCHAR name[UNLEN + 1] = L""; /* Large enough for SID */
@ -352,7 +353,7 @@ user_shared_create (bool reinit)
ProtectHandleINH (cygwin_user_h); ProtectHandleINH (cygwin_user_h);
debug_printf ("user shared version %x", user_shared->version); debug_printf ("user shared version %x", user_shared->version);
if (reinit) if (reinit)
user_shared_initialize (); user_shared->initialize ();
} }
void __stdcall void __stdcall
@ -383,10 +384,21 @@ shared_info::init_obcaseinsensitive ()
debug_printf ("obcaseinsensitive set to %d", obcaseinsensitive); debug_printf ("obcaseinsensitive set to %d", obcaseinsensitive);
} }
void inline
shared_info::create ()
{
cygwin_shared = (shared_info *) open_shared (L"shared",
CYGWIN_VERSION_SHARED_DATA,
cygwin_shared_h,
sizeof (*cygwin_shared),
SH_CYGWIN_SHARED);
cygwin_shared->initialize ();
}
void void
shared_info::initialize () shared_info::initialize ()
{ {
DWORD sversion = (DWORD) InterlockedExchange ((LONG *) &version, SHARED_VERSION_MAGIC); spinlock sversion (version, CURR_SHARED_MAGIC);
if (!sversion) if (!sversion)
{ {
cb = sizeof (*this); cb = sizeof (*this);
@ -394,16 +406,19 @@ shared_info::initialize ()
init_obcaseinsensitive (); /* Initialize obcaseinsensitive */ init_obcaseinsensitive (); /* Initialize obcaseinsensitive */
tty.init (); /* Initialize tty table */ tty.init (); /* Initialize tty table */
mt.initialize (); /* Initialize shared tape information */ mt.initialize (); /* Initialize shared tape information */
/* 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);
} }
else if (sversion != SHARED_VERSION_MAGIC) else if (sversion != (LONG) CURR_SHARED_MAGIC)
{ sversion.multiple_cygwin_problem ("system shared memory version",
InterlockedExchange ((LONG *) &version, sversion); sversion, CURR_SHARED_MAGIC);
multiple_cygwin_problem ("system shared memory version", sversion, SHARED_VERSION_MAGIC); else if (cb != sizeof (*this))
}
if (cb != SHARED_INFO_CB)
system_printf ("size of shared memory region changed from %u to %u", system_printf ("size of shared memory region changed from %u to %u",
SHARED_INFO_CB, cb); sizeof (*this), cb);
heap_init ();
} }
void void
@ -418,30 +433,9 @@ memory_init (bool init_cygheap)
cygheap->user.init (); cygheap->user.init ();
} }
/* Initialize general shared memory under spinlock control */
{
spinlock smi (shared_mem_inited, 10000);
if (!smi)
init_installation_root (); /* Initialize installation root dir */ init_installation_root (); /* Initialize installation root dir */
shared_info::create (); /* Initialize global shared memory */
cygwin_shared = (shared_info *) open_shared (L"shared", user_info::create (false); /* Initialize per-user shared memory */
CYGWIN_VERSION_SHARED_DATA,
cygwin_shared_h,
sizeof (*cygwin_shared),
SH_CYGWIN_SHARED);
heap_init ();
if (!smi)
{
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);
}
}
user_shared_create (false);
} }
unsigned unsigned

View File

@ -16,33 +16,30 @@ details. */
class user_info class user_info
{ {
void initialize ();
public: public:
DWORD version; LONG version;
DWORD cb; DWORD cb;
bool warned_msdos; bool warned_msdos;
mount_info mountinfo; mount_info mountinfo;
friend void dll_crt0_1 (void *);
static void create (bool);
}; };
/******** Shared Info ********/ /******** Shared Info ********/
/* Data accessible to all tasks */ /* Data accessible to all tasks */
#define SHARED_VERSION (unsigned)(cygwin_version.api_major << 8 | \
cygwin_version.api_minor)
#define SHARED_VERSION_MAGIC CYGWIN_VERSION_MAGIC (SHARED_MAGIC, SHARED_VERSION)
#define SHARED_INFO_CB 31136 #define CURR_SHARED_MAGIC 0xcebb78fcU
#define CURR_SHARED_MAGIC 0x18da899eU #define USER_VERSION 1
#define CURR_USER_MAGIC 0x6112afb3U
#define USER_VERSION 1 // increment when mount table changes and
#define USER_VERSION_MAGIC CYGWIN_VERSION_MAGIC (USER_MAGIC, USER_VERSION)
#define CURR_USER_MAGIC 0xb2232e71U
/* NOTE: Do not make gratuitous changes to the names or organization of the /* NOTE: Do not make gratuitous changes to the names or organization of the
below class. The layout is checksummed to determine compatibility between below class. The layout is checksummed to determine compatibility between
different cygwin versions. */ different cygwin versions. */
class shared_info class shared_info
{ {
DWORD version; LONG version;
DWORD cb; DWORD cb;
public: public:
unsigned heap_chunk; unsigned heap_chunk;
@ -58,6 +55,7 @@ class shared_info
void init_obcaseinsensitive (); void init_obcaseinsensitive ();
unsigned heap_chunk_size (); unsigned heap_chunk_size ();
unsigned heap_slop_size (); unsigned heap_slop_size ();
static void create ();
}; };
extern shared_info *cygwin_shared; extern shared_info *cygwin_shared;
@ -104,7 +102,6 @@ void *__stdcall open_shared (const WCHAR *, int, HANDLE&, DWORD,
shared_locations *, PSECURITY_ATTRIBUTES = &sec_all, shared_locations *, PSECURITY_ATTRIBUTES = &sec_all,
DWORD = FILE_MAP_READ | FILE_MAP_WRITE); DWORD = FILE_MAP_READ | FILE_MAP_WRITE);
extern void user_shared_create (bool reinit); extern void user_shared_create (bool reinit);
extern void user_shared_initialize ();
extern void init_installation_root (); extern void init_installation_root ();
extern WCHAR installation_root[PATH_MAX]; extern WCHAR installation_root[PATH_MAX];
extern UNICODE_STRING installation_key; extern UNICODE_STRING installation_key;

View File

@ -11,30 +11,70 @@ details. */
#ifndef _SPINLOCK_H #ifndef _SPINLOCK_H
#define _SPINLOCK_H #define _SPINLOCK_H
#include "hires.h" #include "ntdll.h"
#define SPINLOCK_WAIT (15000LL * 10000LL)
class spinlock class spinlock
{ {
LONG *locker; LONG *locker;
LONG val; LONG val;
LONG setto;
void done (LONG what)
{
if (locker)
{
InterlockedExchange (locker, what);
locker = NULL;
}
}
long long time ()
{
LARGE_INTEGER t;
if (NtQuerySystemTime (&t) == STATUS_SUCCESS)
return get_ll (t);
return 0LL;
}
public: public:
spinlock (LONG& locktest, LONGLONG timeout): spinlock (LONG& locktest, LONG wanted_val = 1, LONGLONG timeout = SPINLOCK_WAIT):
locker (&locktest) locker (&locktest), setto (wanted_val)
{ {
if ((val = locktest) == 1) /* Quick test to see if we're already initialized */
return; if ((val = locktest) == wanted_val)
LONGLONG then = gtod.msecs (); locker = NULL;
for (;;) /* Slightly less quick test to see if we are the first cygwin process */
else if ((val = InterlockedExchange (locker, -1)) == 0)
/* We're armed and dangerous */;
else if (val == wanted_val)
done (val); /* This was initialized while we weren't looking */
else
{ {
if ((val = InterlockedExchange (locker, -1)) != -1 long long then = time ();
|| (gtod.msecs () - then) >= timeout) /* Loop waiting for some other process to set locktest to something
break; other than -1, indicating that initialization has finished. Or,
wait a default of 15 seconds for that to happen and, if it doesn't
just grab the lock ourselves. */
while ((val = InterlockedExchange (locker, -1)) == -1
&& (time () - then) < timeout)
yield (); yield ();
/* Reset the lock back to wanted_value under the assumption that is
what caused the above loop to kick out. */
if (val == -1)
val = 0; /* Timed out. We'll initialize things ourselves. */
else
done (val); /* Put back whatever was there before, assuming that
it is actually wanted_val. */
} }
} }
~spinlock () {InterlockedExchange (locker, 1);} ~spinlock () {done (setto);}
operator LONG () const {return val;} operator LONG () const {return val;}
/* FIXME: This should be handled in a more general fashion, probably by
establishing a linked list of spinlocks which are freed on process exit. */
void multiple_cygwin_problem (const char *w, unsigned m, unsigned v)
{
done (val);
::multiple_cygwin_problem (w, m, v);
}
}; };
#endif /*_SPINLOCK_H*/ #endif /*_SPINLOCK_H*/

View File

@ -2965,7 +2965,7 @@ seteuid32 (__uid32_t uid)
groups.ischanged = FALSE; groups.ischanged = FALSE;
if (!issamesid) if (!issamesid)
/* Recreate and fill out the user shared region for a new user. */ /* Recreate and fill out the user shared region for a new user. */
user_shared_create (true); user_info::create (true);
return 0; return 0;
} }