* 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:
parent
654e623ce0
commit
cef5dfd75a
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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*/
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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*/
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user