Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog22
-rw-r--r--winsup/cygwin/cygerrno.h3
-rw-r--r--winsup/cygwin/errno.cc6
-rw-r--r--winsup/cygwin/flock.cc2
-rw-r--r--winsup/cygwin/ntdll.h13
-rw-r--r--winsup/cygwin/posix_ipc.cc119
6 files changed, 128 insertions, 37 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index bd1381ce1..71c6dae49 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,27 @@
2011-04-28 Corinna Vinschen <corinna@vinschen.de>
+ * cygerrno.h (geterrno_from_nt_status): Declare.
+ * errno.cc (geterrno_from_nt_status): Define.
+ * flock.cc: Fix copyright dates.
+ * ntdll.h (enum _TIMER_TYPE): Define.
+ (PTIMER_APC_ROUTINE): Define.
+ (NtCancelTimer): Declare.
+ (NtCreateTimer): Declare.
+ (NtSetTimer): Declare.
+ * posix_ipc.cc (ipc_cond_timedwait): Rewrite to make interruptible and
+ restartable. Call pthread_testcancel in case of timeout to enable
+ pthread_cancel on waiting thread. Replace WFMO timeout with waiting
+ for a waitable timer. Explain why. Replace single call to WFMO with
+ two calls, one for the event, one for the mutex. Don't lock mutex in
+ case of error.
+ (ipc_cond_signal): Make void function.
+ (ipc_cond_close): Ditto.
+ (_mq_send): Immediately return -1 in case of error from
+ ipc_cond_timedwait.
+ (_mq_receive): Ditto.
+
+2011-04-28 Corinna Vinschen <corinna@vinschen.de>
+
* advapi32.cc (GetSecurityDescriptorDacl): Remove.
(GetSecurityDescriptorGroup): Remove.
(GetSecurityDescriptorOwner): Remove.
diff --git a/winsup/cygwin/cygerrno.h b/winsup/cygwin/cygerrno.h
index e1a1af07d..e63a17cc5 100644
--- a/winsup/cygwin/cygerrno.h
+++ b/winsup/cygwin/cygerrno.h
@@ -1,6 +1,6 @@
/* cygerrno.h: main Cygwin header file.
- Copyright 2000, 2001, 2002, 2003, 2004, 2010 Red Hat, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2004, 2010, 2011 Red Hat, Inc.
This file is part of Cygwin.
@@ -16,6 +16,7 @@ void __stdcall seterrno_from_win_error (const char *file, int line, DWORD code)
void __stdcall seterrno_from_nt_status (const char *file, int line, NTSTATUS status) __attribute__ ((regparm(3)));
void __stdcall seterrno (const char *, int line) __attribute__ ((regparm(2)));
int __stdcall geterrno_from_win_error (DWORD code = GetLastError (), int deferrno = 13 /*EACCESS*/) __attribute__ ((regparm(2)));
+int __stdcall geterrno_from_nt_status (NTSTATUS status, int deferrno = 13 /*EACCESS*/) __attribute__ ((regparm(2)));
#define __seterrno() seterrno (__FILE__, __LINE__)
#define __seterrno_from_win_error(val) seterrno_from_win_error (__FILE__, __LINE__, val)
diff --git a/winsup/cygwin/errno.cc b/winsup/cygwin/errno.cc
index b83760926..0df53df63 100644
--- a/winsup/cygwin/errno.cc
+++ b/winsup/cygwin/errno.cc
@@ -327,6 +327,12 @@ seterrno_from_win_error (const char *file, int line, DWORD code)
errno = _impure_ptr->_errno = geterrno_from_win_error (code, EACCES);
}
+int __stdcall
+geterrno_from_nt_status (NTSTATUS status, int deferrno)
+{
+ return geterrno_from_win_error (RtlNtStatusToDosError (status));
+}
+
/* seterrno_from_nt_status: Given a NT status code, set errno
as appropriate. */
void __stdcall
diff --git a/winsup/cygwin/flock.cc b/winsup/cygwin/flock.cc
index 16e2911a6..90128175f 100644
--- a/winsup/cygwin/flock.cc
+++ b/winsup/cygwin/flock.cc
@@ -1,6 +1,6 @@
/* flock.cc. NT specific implementation of advisory file locking.
- Copyright 2003, 2008, 2009 Red Hat, Inc.
+ Copyright 2003, 2008, 2009, 2010, 2011 Red Hat, Inc.
This file is part of Cygwin.
diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index 8f13e1c6c..e9ff11bf0 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -948,6 +948,14 @@ typedef struct _KEY_VALUE_PARTIAL_INFORMATION
UCHAR Data[1];
} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;
+typedef enum _TIMER_TYPE
+{
+ NotificationTimer,
+ SynchronisationTimer
+} TIMER_TYPE, *PTIMER_TYPE;
+
+typedef VOID (APIENTRY *PTIMER_APC_ROUTINE)(PVOID, ULONG, ULONG);
+
/* Function declarations for ntdll.dll. These don't appear in any
standard Win32 header. */
@@ -970,6 +978,7 @@ extern "C"
ULONG, PTOKEN_PRIVILEGES, PULONG);
NTSTATUS NTAPI NtAllocateLocallyUniqueId (PLUID);
NTSTATUS NTAPI NtAllocateUuids (PLARGE_INTEGER, PULONG, PULONG, PUCHAR);
+ NTSTATUS NTAPI NtCancelTimer (HANDLE, PBOOLEAN);
NTSTATUS NTAPI NtClose (HANDLE);
NTSTATUS NTAPI NtCommitTransaction (HANDLE, BOOLEAN);
NTSTATUS NTAPI NtCreateDirectoryObject (PHANDLE, ACCESS_MASK,
@@ -990,6 +999,8 @@ extern "C"
PLARGE_INTEGER, ULONG, ULONG, HANDLE);
NTSTATUS NTAPI NtCreateSemaphore (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
LONG, LONG);
+ NTSTATUS NTAPI NtCreateTimer (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
+ TIMER_TYPE);
NTSTATUS NTAPI NtCreateToken (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
TOKEN_TYPE, PLUID, PLARGE_INTEGER, PTOKEN_USER,
PTOKEN_GROUPS, PTOKEN_PRIVILEGES, PTOKEN_OWNER,
@@ -1081,6 +1092,8 @@ extern "C"
ULONG);
NTSTATUS NTAPI NtSetSecurityObject (HANDLE, SECURITY_INFORMATION,
PSECURITY_DESCRIPTOR);
+ NTSTATUS NTAPI NtSetTimer (HANDLE, PLARGE_INTEGER, PTIMER_APC_ROUTINE, PVOID,
+ BOOLEAN, LONG, PBOOLEAN);
NTSTATUS NTAPI NtSetTimerResolution (ULONG, BOOLEAN, PULONG);
NTSTATUS NTAPI NtSetValueKey (HANDLE, PUNICODE_STRING, ULONG, ULONG, PVOID,
ULONG);
diff --git a/winsup/cygwin/posix_ipc.cc b/winsup/cygwin/posix_ipc.cc
index c7b2bc0fe..600fb0d19 100644
--- a/winsup/cygwin/posix_ipc.cc
+++ b/winsup/cygwin/posix_ipc.cc
@@ -174,55 +174,104 @@ ipc_cond_init (HANDLE *pevt, const char *name, char sr)
static int
ipc_cond_timedwait (HANDLE evt, HANDLE mtx, const struct timespec *abstime)
{
- struct timeval tv;
- DWORD timeout;
- HANDLE h[2] = { mtx, evt };
- int err;
-
- if (!abstime)
- timeout = INFINITE;
- else if (abstime->tv_sec < 0
- || abstime->tv_nsec < 0
- || abstime->tv_nsec > 999999999)
- return EINVAL;
- else
+ HANDLE w4[3] = { evt, signal_arrived, NULL };
+ DWORD cnt = 2;
+ int ret = 0;
+
+ if (abstime)
{
- gettimeofday (&tv, NULL);
- /* Check for immediate timeout. */
- if (tv.tv_sec > abstime->tv_sec
- || (tv.tv_sec == abstime->tv_sec
- && tv.tv_usec > abstime->tv_nsec / 1000))
- return ETIMEDOUT;
- timeout = (abstime->tv_sec - tv.tv_sec) * 1000;
- timeout += (abstime->tv_nsec / 1000 - tv.tv_usec) / 1000;
+ if (abstime->tv_sec < 0
+ || abstime->tv_nsec < 0
+ || abstime->tv_nsec > 999999999)
+ return EINVAL;
+
+ /* If a timeout is set, we create a waitable timer to wait for.
+ This is the easiest way to handle the absolute timeout value, given
+ that NtSetTimer also takes absolute times and given the double
+ dependency on evt *and* mtx, which requires to call WFMO twice. */
+ NTSTATUS status;
+ LARGE_INTEGER duetime;
+
+ status = NtCreateTimer (&w4[2], TIMER_ALL_ACCESS, NULL,
+ NotificationTimer);
+ if (!NT_SUCCESS (status))
+ return geterrno_from_nt_status (status);
+ timespec_to_filetime (abstime, (FILETIME *) &duetime);
+ status = NtSetTimer (w4[2], &duetime, NULL, NULL, FALSE, 0, NULL);
+ if (!NT_SUCCESS (status))
+ {
+ NtClose (w4[2]);
+ return geterrno_from_nt_status (status);
+ }
+ cnt = 3;
}
ResetEvent (evt);
- if ((err = ipc_mutex_unlock (mtx)) != 0)
- return err;
- switch (WaitForMultipleObjects (2, h, TRUE, timeout))
+ if ((ret = ipc_mutex_unlock (mtx)) != 0)
+ return ret;
+ /* Everything's set up, so now wait for the event to be signalled. */
+restart1:
+ switch (WaitForMultipleObjects (cnt, w4, FALSE, INFINITE))
{
case WAIT_OBJECT_0:
- case WAIT_ABANDONED_0:
- return 0;
- case WAIT_TIMEOUT:
- ipc_mutex_lock (mtx);
- return ETIMEDOUT;
+ break;
+ case WAIT_OBJECT_0 + 1:
+ if (_my_tls.call_signal_handler ())
+ goto restart1;
+ ret = EINTR;
+ break;
+ case WAIT_OBJECT_0 + 2:
+ pthread_testcancel ();
+ ret = ETIMEDOUT;
+ break;
default:
+ ret = geterrno_from_win_error ();
break;
}
- return geterrno_from_win_error ();
+ if (ret == 0)
+ {
+ /* At this point we need to lock the mutex. The wait is practically
+ the same as before, just that we now wait on the mutex instead of the
+ event. */
+ restart2:
+ w4[0] = mtx;
+ switch (WaitForMultipleObjects (cnt, w4, FALSE, INFINITE))
+ {
+ case WAIT_OBJECT_0:
+ case WAIT_ABANDONED_0:
+ break;
+ case WAIT_OBJECT_0 + 1:
+ if (_my_tls.call_signal_handler ())
+ goto restart2;
+ ret = EINTR;
+ break;
+ case WAIT_OBJECT_0 + 2:
+ pthread_testcancel ();
+ ret = ETIMEDOUT;
+ break;
+ default:
+ ret = geterrno_from_win_error ();
+ break;
+ }
+ }
+ if (w4[2])
+ {
+ if (ret != ETIMEDOUT)
+ NtCancelTimer (w4[2], NULL);
+ NtClose (w4[2]);
+ }
+ return ret;
}
-static inline int
+static inline void
ipc_cond_signal (HANDLE evt)
{
- return SetEvent (evt) ? 0 : geterrno_from_win_error ();
+ SetEvent (evt);
}
-static inline int
+static inline void
ipc_cond_close (HANDLE evt)
{
- return CloseHandle (evt) ? 0 : geterrno_from_win_error ();
+ CloseHandle (evt);
}
class ipc_flock
@@ -736,7 +785,7 @@ _mq_send (mqd_t mqd, const char *ptr, size_t len, unsigned int prio,
if (ret != 0)
{
set_errno (ret);
- goto err;
+ return -1;
}
}
}
@@ -851,7 +900,7 @@ _mq_receive (mqd_t mqd, char *ptr, size_t maxlen, unsigned int *priop,
if (ret != 0)
{
set_errno (ret);
- goto err;
+ return -1;
}
}
mqhdr->mqh_nwait--;