diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index c7392b57d..f0a607908 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,9 @@ +2004-05-15 Christopher Faylor + + * cygheap.h: Remove some parameter names from declarations throughout. + (cygheap::set): Reflect changes in declaration for arguments and return + value from previous checkin. + 2004-05-15 Pierre Humblet * cygheap.h (cwdstuff::set): Modify return value and arguments. @@ -57,7 +63,7 @@ variables while issetuid. 2004-05-08 Pierre Humblet - Christopher Faylor + Christopher Faylor * syscalls.cc: Include environ.h. (chroot): Set errno in case of path error. Call getwinenv. @@ -115,7 +121,7 @@ * path.cc (path_conv::check): Strip trailing dots and spaces and return error if the final component had only dots and spaces. (normalize_posix_path): Revert 2004-04-30. - (chdir): Do not check for trailing spaces. Do not set native_dir + (chdir): Do not check for trailing spaces. Do not set native_dir to c:\ for virtual devices. Pass only native_dir to cwd.set. (cwdstuff::set): Assume posix_cwd is already normalized. diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index a32e0d5d1..15b179ea0 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -82,7 +82,7 @@ public: return p; } bool exists () {return !!m;} - void set (const char *posix, const char *native); + void set (const char *, const char *); size_t posix_length () const { return m->posix_pathlen; } const char *posix_path () const { return m->posix_path; } size_t native_length () const { return m->native_pathlen; } @@ -217,12 +217,12 @@ struct cwdstuff char *win32; DWORD hash; muto *cwd_lock; - char *get (char *buf, int need_posix = 1, int with_chroot = 0, unsigned ulen = CYG_MAX_PATH); + char *get (char *, int = 1, int = 0, unsigned = CYG_MAX_PATH); DWORD get_hash (); void init (); - void fixup_after_exec (char *win32, char *posix, DWORD hash); + void fixup_after_exec (char *, char *, DWORD); bool get_initial (); - void set (const char *win32_cwd, const char *posix_cwd = NULL); + int set (const char *, const char *, bool); }; #ifdef DEBUGGING diff --git a/winsup/cygwin/cygthread.h b/winsup/cygwin/cygthread.h index 9d10bb266..cc8dbc98c 100644 --- a/winsup/cygwin/cygthread.h +++ b/winsup/cygwin/cygthread.h @@ -41,6 +41,7 @@ class cygthread (void) CloseHandle (h); h = NULL; } + DWORD tid () const {return id;} }; #define cygself NULL diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index aee32ac1b..56b068cc5 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -32,6 +32,7 @@ #include "sigproc.h" #include "cygthread.h" #include "select.h" +#include "wininfo.h" #include extern bool fdsock (cygheap_fdmanip& fd, const device *, SOCKET soc); @@ -1374,7 +1375,7 @@ fhandler_socket::ioctl (unsigned int cmd, void *p) break; } case FIOASYNC: - res = WSAAsyncSelect (get_socket (), gethwnd (), WM_ASYNCIO, + res = WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO, *(int *) p ? ASYNC_MASK : 0); syscall_printf ("Async I/O on socket %s", *(int *) p ? "started" : "cancelled"); @@ -1390,7 +1391,7 @@ fhandler_socket::ioctl (unsigned int cmd, void *p) * blocking mode */ if (cmd == FIONBIO && *(int *) p == 0) - WSAAsyncSelect (get_socket (), gethwnd (), 0, 0); + WSAAsyncSelect (get_socket (), winmsg, 0, 0); res = ioctlsocket (get_socket (), cmd, (unsigned long *) p); if (res == SOCKET_ERROR) set_winsock_errno (); @@ -1400,7 +1401,7 @@ fhandler_socket::ioctl (unsigned int cmd, void *p) *(int *) p ? "non" : ""); /* Start AsyncSelect if async socket unblocked */ if (*(int *) p && async_io ()) - WSAAsyncSelect (get_socket (), gethwnd (), WM_ASYNCIO, ASYNC_MASK); + WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO, ASYNC_MASK); set_nonblocking (*(int *) p); } diff --git a/winsup/cygwin/sync.cc b/winsup/cygwin/sync.cc index bd89793fd..b3eacd9c1 100644 --- a/winsup/cygwin/sync.cc +++ b/winsup/cygwin/sync.cc @@ -125,6 +125,16 @@ muto::release () threads waiting for the lock, so trigger bruteforce. */ if (InterlockedDecrement (&waiters) >= 0) (void) SetEvent (bruteforce); /* Wake up one of the waiting threads */ + else if (*name == '!') + { + CloseHandle (bruteforce); /* If *name == '!' and there are no + other waiters, then this is the + last time this muto will ever be + used, so close the handle. */ +#ifdef DEBUGGING + bruteforce = NULL; +#endif + } } return 1; /* success. */ diff --git a/winsup/cygwin/sync.h b/winsup/cygwin/sync.h index 24de97428..32ca14766 100644 --- a/winsup/cygwin/sync.h +++ b/winsup/cygwin/sync.h @@ -38,7 +38,6 @@ public: /* Return true if caller thread owns the lock. */ int ismine () {return tid == GetCurrentThreadId ();} DWORD owner () {return tid;} - int unstable () {return !tid && (sync || waiters >= 0);} void reset () __attribute__ ((regparm (1))); bool acquired (); static void set_exiting_thread () {exiting_thread = GetCurrentThreadId ();} @@ -59,4 +58,11 @@ extern muto muto_start; static muto __storage __attribute__((nocommon)) __attribute__((section(".data_cygwin_nocopy1"))); \ __name = __storage.init (#__name); \ }) + +/* Use a statically allocated buffer as the storage for a muto */ +#define new_muto_name(__var, __name) \ +({ \ + static muto __var##_storage __attribute__((nocommon)) __attribute__((section(".data_cygwin_nocopy1"))); \ + __var = __var##_storage.init (__name); \ +}) #endif /*_SYNC_H*/ diff --git a/winsup/cygwin/window.cc b/winsup/cygwin/window.cc index d005ae69b..554be3a5e 100644 --- a/winsup/cygwin/window.cc +++ b/winsup/cygwin/window.cc @@ -24,14 +24,21 @@ details. */ #include "perprocess.h" #include "security.h" #include "cygthread.h" +#include "sync.h" +static DWORD WINAPI winthread (VOID *); +#include "wininfo.h" -static NO_COPY UINT timer_active = 0; -static NO_COPY struct itimerval itv; -static NO_COPY DWORD start_time; -static NO_COPY HWND ourhwnd = NULL; +wininfo NO_COPY winmsg; -static LRESULT CALLBACK -WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +muto NO_COPY *wininfo::lock; + +wininfo::wininfo () +{ + new_muto_name (lock, "!winlock"); +} + +int __stdcall +wininfo::process (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { #ifndef NOSTRACE strace.wm (uMsg, wParam, lParam); @@ -50,9 +57,7 @@ WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) itv.it_interval.tv_usec / 1000; KillTimer (hwnd, timer_active); if (!elapse) - { - timer_active = 0; - } + timer_active = 0; else { timer_active = SetTimer (hwnd, 1, elapse, NULL); @@ -73,10 +78,15 @@ WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } } -static HANDLE window_started; +static LRESULT CALLBACK +process_window_events (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return winmsg.process (hwnd, uMsg, wParam, lParam); +} +/* Handle windows events. Inherits ownership of the wininfo lock */ static DWORD WINAPI -Winmain (VOID *) +winthread (VOID *arg) { MSG msg; WNDCLASS wc; @@ -85,7 +95,7 @@ Winmain (VOID *) /* Register the window class for the main window. */ wc.style = 0; - wc.lpfnWndProc = (WNDPROC) WndProc; + wc.lpfnWndProc = (WNDPROC) process_window_events; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = user_data->hmodule; @@ -96,60 +106,64 @@ Winmain (VOID *) wc.lpszClassName = classname; if (!RegisterClass (&wc)) - { - system_printf ("Cannot register window class, %E"); - return FALSE; - } + api_fatal ("cannot register window class, %E"); + wininfo *wi = (wininfo *) arg; /* Create hidden window. */ - ourhwnd = CreateWindow (classname, classname, WS_POPUP, CW_USEDEFAULT, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - (HWND) NULL, (HMENU) NULL, user_data->hmodule, - (LPVOID) NULL); + wi->hwnd = CreateWindow (classname, classname, WS_POPUP, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + (HWND) NULL, (HMENU) NULL, user_data->hmodule, + (LPVOID) NULL); + if (!wi->hwnd) + api_fatal ("couldn't create window, %E"); + wi->lock->release (); - SetEvent (window_started); - - if (!ourhwnd) - { - system_printf ("Cannot create window"); - return FALSE; - } - - /* Start the message loop. */ - - while (GetMessage (&msg, ourhwnd, 0, 0) == TRUE) + while (GetMessage (&msg, (HWND) arg, 0, 0) == TRUE) DispatchMessage (&msg); return 0; } -HWND __stdcall -gethwnd () +wininfo::operator +HWND () { - if (ourhwnd != NULL) - return ourhwnd; + if (hwnd) + return hwnd; - cygthread *h; +console_printf ("hwnd is NULL\n"); + lock->acquire (); + if (hwnd) + { +console_printf ("hwnd acquired %p\n", hwnd); + lock->release (); + return hwnd; + } - window_started = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); - h = new cygthread (Winmain, NULL, "win"); +console_printf ("creating window\n"); + + cygthread *h = new cygthread (winthread, this, "win"); h->SetThreadPriority (THREAD_PRIORITY_HIGHEST); - WaitForSingleObject (window_started, INFINITE); - CloseHandle (window_started); h->zap_h (); - return ourhwnd; + while (!hwnd) + low_priority_sleep (0); + return hwnd; } extern "C" int setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue) { - UINT elapse; - if (which != ITIMER_REAL) { set_errno (ENOSYS); return -1; } + return winmsg.setitimer (value, oldvalue); +} + +/* FIXME: Very racy */ +int __stdcall +wininfo::setitimer (const struct itimerval *value, struct itimerval *oldvalue) +{ /* Check if we will wrap */ if (itv.it_value.tv_sec >= (long) (UINT_MAX / 1000)) { @@ -158,7 +172,7 @@ setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue) } if (timer_active) { - KillTimer (gethwnd (), timer_active); + KillTimer (winmsg, timer_active); timer_active = 0; } if (oldvalue) @@ -169,13 +183,13 @@ setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue) return -1; } itv = *value; - elapse = itv.it_value.tv_sec * 1000 + itv.it_value.tv_usec / 1000; + UINT elapse = itv.it_value.tv_sec * 1000 + itv.it_value.tv_usec / 1000; if (elapse == 0) if (itv.it_value.tv_usec) elapse = 1; else return 0; - if (!(timer_active = SetTimer (gethwnd (), 1, elapse, NULL))) + if (!(timer_active = SetTimer (winmsg, 1, elapse, NULL))) { __seterrno (); return -1; @@ -187,8 +201,6 @@ setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue) extern "C" int getitimer (int which, struct itimerval *value) { - UINT elapse, val; - if (which != ITIMER_REAL) { set_errno (EINVAL); @@ -199,6 +211,13 @@ getitimer (int which, struct itimerval *value) set_errno (EFAULT); return -1; } + return winmsg.getitimer (value); +} + +/* FIXME: racy */ +int __stdcall +wininfo::getitimer (struct itimerval *value) +{ *value = itv; if (!timer_active) { @@ -206,6 +225,9 @@ getitimer (int which, struct itimerval *value) value->it_value.tv_usec = 0; return 0; } + + UINT elapse, val; + elapse = GetTickCount () - start_time; val = itv.it_value.tv_sec * 1000 + itv.it_value.tv_usec / 1000; val -= elapse; diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index 4c57c3776..cd698ba56 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -217,8 +217,6 @@ void events_terminate (void); void __stdcall close_all_files (); -/* Invisible window initialization/termination. */ -HWND __stdcall gethwnd (void); /* Check if running in a visible window station. */ extern bool has_visible_window_station (void);