From bd3b3783f8d2b80eef694324c6d0c143613b05be Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Tue, 9 Mar 2010 21:26:55 +0000 Subject: [PATCH] * shared_info.h (open_shared): Create function wrapper for common use case. (open_shared): Change fifth argument to a pointer rather than a reference. * fhandler_console.cc (fhandler_console::get_tty_stuff): Eliminate use of dummy variable and call open_shared with constant. * fhandler_process.cc (format_process_mounts): Ditto. * pinfo.cc (pinfo::init): Pass pointer to shloc. * shared.cc (shared_mem_inited): New variable. (open_shared): Crate function wrapper for common use case. (open_shared): Accommodate change to fifth argument to a pointer. (shared_info::initialize): Remove spinlock test. Simplify function. Move get_session_parent_dir call back here. (memory_init): Protect global shared settings with shared_mem_inited spinlock. Move get_session_parent_dir call to shared_info::initialize. --- winsup/cygwin/ChangeLog | 18 ++++++ winsup/cygwin/fhandler_console.cc | 3 +- winsup/cygwin/fhandler_process.cc | 3 +- winsup/cygwin/pinfo.cc | 2 +- winsup/cygwin/shared.cc | 96 +++++++++++++++++++------------ winsup/cygwin/shared_info.h | 10 ++-- 6 files changed, 85 insertions(+), 47 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 1d5f86747..7532faa6c 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,21 @@ +2010-03-09 Christopher Faylor + + * shared_info.h (open_shared): Create function wrapper for common use + case. + (open_shared): Change fifth argument to a pointer rather than a + reference. + * fhandler_console.cc (fhandler_console::get_tty_stuff): Eliminate use + of dummy variable and call open_shared with constant. + * fhandler_process.cc (format_process_mounts): Ditto. + * pinfo.cc (pinfo::init): Pass pointer to shloc. + * shared.cc (shared_mem_inited): New variable. + (open_shared): Crate function wrapper for common use case. + (open_shared): Accommodate change to fifth argument to a pointer. + (shared_info::initialize): Remove spinlock test. Simplify function. + Move get_session_parent_dir call back here. + (memory_init): Protect global shared settings with shared_mem_inited + spinlock. Move get_session_parent_dir call to shared_info::initialize. + 2010-03-09 Christopher Faylor * shared.cc (inst_root_inited): Delete. diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 7a11fd22f..0917b0bab 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -83,11 +83,10 @@ fhandler_console::get_tty_stuff (int flags = 0) if (dev_state) return &shared_console_info->tty_min_state; - shared_locations sh_shared_console = SH_SHARED_CONSOLE; shared_console_info = (console_state *) open_shared (NULL, 0, cygheap->console_h, sizeof (*shared_console_info), - sh_shared_console); + SH_SHARED_CONSOLE); dev_state = &shared_console_info->dev_state; ProtectHandleINH (cygheap->console_h); diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index fa8aff7c6..10610541f 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -897,7 +897,6 @@ format_process_mounts (void *data, char *&destbuf) if (p->pid != myself->pid) { WCHAR sid_string[UNLEN + 1] = L""; /* Large enough for SID */ - shared_locations sl = SH_JUSTOPEN; cygsid p_sid; @@ -905,7 +904,7 @@ format_process_mounts (void *data, char *&destbuf) return 0; p_sid.string (sid_string); u_shared = (user_info *) open_shared (sid_string, USER_VERSION, u_hdl, - sizeof (user_info), sl, + sizeof (user_info), SH_JUSTOPEN, &sec_none_nih); if (!u_shared) return 0; diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index f772b42a8..af081bafa 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -236,7 +236,7 @@ pinfo::init (pid_t n, DWORD flag, HANDLE h0) else mapsize = sizeof (_pinfo); - procinfo = (_pinfo *) open_shared (L"cygpid", n, h0, mapsize, shloc, + procinfo = (_pinfo *) open_shared (L"cygpid", n, h0, mapsize, &shloc, sec_attribs, access); if (!h0) { diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc index 53c3c1894..03118daf0 100644 --- a/winsup/cygwin/shared.cc +++ b/winsup/cygwin/shared.cc @@ -37,6 +37,7 @@ HANDLE NO_COPY cygwin_user_h; WCHAR installation_root[PATH_MAX] __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)); +static LONG shared_mem_inited __attribute__((section (".cygwin_dll_common"), shared)); /* Use absolute path of cygwin1.dll to derive the Win32 dir which is our installation_root. Note that we can't handle Cygwin installation @@ -114,7 +115,6 @@ init_installation_root () installation_key.Length = 0; installation_key.Buffer[0] = L'\0'; } - } /* This function returns a handle to the top-level directory in the global @@ -216,16 +216,23 @@ static ptrdiff_t offsets[] = void * __stdcall open_shared (const WCHAR *name, int n, HANDLE& shared_h, DWORD size, - shared_locations& m, PSECURITY_ATTRIBUTES psa, DWORD access) + shared_locations m, PSECURITY_ATTRIBUTES psa, DWORD access) +{ + return open_shared (name, n, shared_h, size, &m, psa, access); +} + +void * __stdcall +open_shared (const WCHAR *name, int n, HANDLE& shared_h, DWORD size, + shared_locations *m, PSECURITY_ATTRIBUTES psa, DWORD access) { void *shared; void *addr; - if (m == SH_JUSTCREATE || m == SH_JUSTOPEN) + if (*m == SH_JUSTCREATE || *m == SH_JUSTOPEN) addr = NULL; else { - addr = off_addr (m); + addr = off_addr (*m); VirtualFree (addr, 0, MEM_RELEASE); } @@ -233,23 +240,23 @@ open_shared (const WCHAR *name, int n, HANDLE& shared_h, DWORD size, WCHAR *mapname = NULL; if (shared_h) - m = SH_JUSTOPEN; + *m = SH_JUSTOPEN; else { if (name) mapname = shared_name (map_buf, name, n); - if (m == SH_JUSTOPEN) + if (*m == SH_JUSTOPEN) shared_h = OpenFileMappingW (access, FALSE, mapname); else { shared_h = CreateFileMappingW (INVALID_HANDLE_VALUE, psa, PAGE_READWRITE, 0, size, mapname); if (GetLastError () == ERROR_ALREADY_EXISTS) - m = SH_JUSTOPEN; + *m = SH_JUSTOPEN; } if (shared_h) /* ok! */; - else if (m != SH_JUSTOPEN) + else if (*m != SH_JUSTOPEN) api_fatal ("CreateFileMapping %W, %E. Terminating.", mapname); else return NULL; @@ -272,7 +279,7 @@ open_shared (const WCHAR *name, int n, HANDLE& shared_h, DWORD size, if (!shared) api_fatal ("MapViewOfFileEx '%W'(%p), %E. Terminating.", mapname, shared_h); - if (m == SH_CYGWIN_SHARED && offsets[0]) + if (*m == SH_CYGWIN_SHARED && offsets[0]) { ptrdiff_t delta = (caddr_t) shared - (caddr_t) off_addr (0); offsets[0] = (caddr_t) shared - (caddr_t) cygwin_hmodule; @@ -337,10 +344,9 @@ user_shared_create (bool reinit) if (!cygwin_user_h) cygheap->user.get_windows_id (name); - shared_locations sh_user_shared = SH_USER_SHARED; user_shared = (user_info *) open_shared (name, USER_VERSION, - cygwin_user_h, sizeof (user_info), - sh_user_shared, &sec_none); + cygwin_user_h, sizeof (user_info), + SH_USER_SHARED, &sec_none); debug_printf ("opening user shared for '%W' at %p", name, user_shared); ProtectHandleINH (cygwin_user_h); debug_printf ("user shared version %x", user_shared->version); @@ -382,26 +388,16 @@ shared_info::initialize () DWORD sversion = (DWORD) InterlockedExchange ((LONG *) &version, SHARED_VERSION_MAGIC); if (!sversion) { - /* Initialize installation root dir. This is put here just to piggyback on the - shared memory spinlock. The installation root does not live in shared_info - shared memory. */ - init_installation_root (); - init_obcaseinsensitive ();/* Initialize obcaseinsensitive. */ - tty.init (); /* Initialize tty table. */ - mt.initialize (); /* Initialize shared tape information. */ - debug_printf ("Installation root: <%W> key: <%S>", - installation_root, &installation_key); - cb = sizeof (*this); /* Do last, after all shared memory initialization */ + cb = sizeof (*this); + get_session_parent_dir (); /* Create session dir if first process. */ + init_obcaseinsensitive (); /* Initialize obcaseinsensitive */ + tty.init (); /* Initialize tty table */ + mt.initialize (); /* Initialize shared tape information */ } - else + else if (sversion != SHARED_VERSION_MAGIC) { - if (sversion != SHARED_VERSION_MAGIC) - { - InterlockedExchange ((LONG *) &version, sversion); - multiple_cygwin_problem ("system shared memory version", sversion, SHARED_VERSION_MAGIC); - } - while (!cb) - low_priority_sleep (0); // Should be hit only very very rarely + InterlockedExchange ((LONG *) &version, sversion); + multiple_cygwin_problem ("system shared memory version", sversion, SHARED_VERSION_MAGIC); } if (cb != SHARED_INFO_CB) @@ -422,15 +418,39 @@ memory_init (bool init_cygheap) } /* Initialize general shared memory */ - shared_locations sh_cygwin_shared; - cygwin_shared = (shared_info *) open_shared (L"shared", - CYGWIN_VERSION_SHARED_DATA, - cygwin_shared_h, - sizeof (*cygwin_shared), - sh_cygwin_shared = SH_CYGWIN_SHARED); - cygwin_shared->initialize (); + for (;;) + { + LONG smi = InterlockedExchange (&shared_mem_inited, -1); + if (smi < 0) + { + low_priority_sleep (0); + continue; + } + + if (!smi) + /* Initialize installation root dir */ + init_installation_root (); + + /* Installation root dir has been globally initialized */ + cygwin_shared = (shared_info *) open_shared (L"shared", + CYGWIN_VERSION_SHARED_DATA, + cygwin_shared_h, + sizeof (*cygwin_shared), + SH_CYGWIN_SHARED); + 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); + smi = 1; + } + InterlockedExchange (&shared_mem_inited, smi); + break; + } heap_init (); - get_session_parent_dir (); /* Create session dir if first process. */ user_shared_create (false); } diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h index 1fcb8ff86..52e6ce3df 100644 --- a/winsup/cygwin/shared_info.h +++ b/winsup/cygwin/shared_info.h @@ -97,10 +97,12 @@ HANDLE get_shared_parent_dir (); HANDLE get_session_parent_dir (); char *__stdcall shared_name (char *, const char *, int); WCHAR *__stdcall shared_name (WCHAR *, const WCHAR *, int); -void *__stdcall open_shared (const WCHAR *name, int n, HANDLE &shared_h, - DWORD size, shared_locations&, - PSECURITY_ATTRIBUTES psa = &sec_all, - DWORD access = FILE_MAP_READ | FILE_MAP_WRITE); +void *__stdcall open_shared (const WCHAR *, int, HANDLE&, DWORD, + shared_locations, PSECURITY_ATTRIBUTES = &sec_all, + DWORD = FILE_MAP_READ | FILE_MAP_WRITE); +void *__stdcall open_shared (const WCHAR *, int, HANDLE&, DWORD, + shared_locations *, PSECURITY_ATTRIBUTES = &sec_all, + DWORD = FILE_MAP_READ | FILE_MAP_WRITE); extern void user_shared_create (bool reinit); extern void user_shared_initialize (); extern void init_installation_root ();