* posix_ipc.cc (ipc_mutex_init): Call NtCreateMutant to make sure the
access mask is correct. (ipc_cond_init): Take additional parameter to differ between send and receive event. Call NtCreateEvent to make sure the access mask is correct. (ipc_cond_timedwait): Reset Event prior to calling WFMO. (struct mq_info): Split mqi_wait into two events, mqi_waitsend and mqi_waitrecv. (mq_open): Calloc mqinfo. Create mqi_waitsend and mqi_waitrecv events. Make sure all synchronization objects are closed in case of an error. (_mq_send): Wait for mqi_waitsend event. Signal mqi_waitrecv event. (_mq_receive): Wait for mqi_waitrecv event. Signal mqi_waitsend event. (mq_close): Close mqi_waitsend and mqi_waitrecv events.
This commit is contained in:
parent
c725984f70
commit
3748b3e8e7
|
@ -1,3 +1,19 @@
|
|||
2010-09-06 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* posix_ipc.cc (ipc_mutex_init): Call NtCreateMutant to make sure the
|
||||
access mask is correct.
|
||||
(ipc_cond_init): Take additional parameter to differ between send and
|
||||
receive event. Call NtCreateEvent to make sure the access mask is
|
||||
correct.
|
||||
(ipc_cond_timedwait): Reset Event prior to calling WFMO.
|
||||
(struct mq_info): Split mqi_wait into two events, mqi_waitsend and
|
||||
mqi_waitrecv.
|
||||
(mq_open): Calloc mqinfo. Create mqi_waitsend and mqi_waitrecv events.
|
||||
Make sure all synchronization objects are closed in case of an error.
|
||||
(_mq_send): Wait for mqi_waitsend event. Signal mqi_waitrecv event.
|
||||
(_mq_receive): Wait for mqi_waitrecv event. Signal mqi_waitsend event.
|
||||
(mq_close): Close mqi_waitsend and mqi_waitrecv events.
|
||||
|
||||
2010-09-05 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* path.h (enum pathconv_arg): Remove PC_CHECK_EA.
|
||||
|
|
|
@ -9,6 +9,7 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
|||
details. */
|
||||
|
||||
#include "winsup.h"
|
||||
#include "shared_info.h"
|
||||
#include "thread.h"
|
||||
#include "path.h"
|
||||
#include "cygtls.h"
|
||||
|
@ -95,15 +96,24 @@ check_path (char *res_name, ipc_type_t type, const char *name, size_t len)
|
|||
static int
|
||||
ipc_mutex_init (HANDLE *pmtx, const char *name)
|
||||
{
|
||||
char buf[MAX_PATH];
|
||||
SECURITY_ATTRIBUTES sa = sec_none;
|
||||
WCHAR buf[MAX_PATH];
|
||||
UNICODE_STRING uname;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS status;
|
||||
|
||||
__small_sprintf (buf, "mqueue/mtx_%s", name);
|
||||
sa.lpSecurityDescriptor = everyone_sd (CYG_MUTANT_ACCESS);
|
||||
*pmtx = CreateMutex (&sa, FALSE, buf);
|
||||
if (!*pmtx)
|
||||
debug_printf ("CreateMutex: %E");
|
||||
return *pmtx ? 0 : geterrno_from_win_error ();
|
||||
__small_swprintf (buf, L"mqueue/mtx_%s", name);
|
||||
RtlInitUnicodeString (&uname, buf);
|
||||
InitializeObjectAttributes (&attr, &uname,
|
||||
OBJ_INHERIT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
|
||||
get_shared_parent_dir (),
|
||||
everyone_sd (CYG_MUTANT_ACCESS));
|
||||
status = NtCreateMutant (pmtx, CYG_MUTANT_ACCESS, &attr, FALSE);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
debug_printf ("NtCreateMutant: %p", status);
|
||||
return geterrno_from_win_error (RtlNtStatusToDosError (status));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -138,17 +148,27 @@ ipc_mutex_close (HANDLE mtx)
|
|||
}
|
||||
|
||||
static int
|
||||
ipc_cond_init (HANDLE *pevt, const char *name)
|
||||
ipc_cond_init (HANDLE *pevt, const char *name, char sr)
|
||||
{
|
||||
char buf[MAX_PATH];
|
||||
SECURITY_ATTRIBUTES sa = sec_none;
|
||||
WCHAR buf[MAX_PATH];
|
||||
UNICODE_STRING uname;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS status;
|
||||
|
||||
__small_sprintf (buf, "mqueue/evt_%s", name);
|
||||
sa.lpSecurityDescriptor = everyone_sd (CYG_EVENT_ACCESS);
|
||||
*pevt = CreateEvent (&sa, TRUE, FALSE, buf);
|
||||
if (!*pevt)
|
||||
debug_printf ("CreateEvent: %E");
|
||||
return *pevt ? 0 : geterrno_from_win_error ();
|
||||
__small_swprintf (buf, L"mqueue/evt_%s%c", name, sr);
|
||||
RtlInitUnicodeString (&uname, buf);
|
||||
InitializeObjectAttributes (&attr, &uname,
|
||||
OBJ_INHERIT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
|
||||
get_shared_parent_dir (),
|
||||
everyone_sd (CYG_EVENT_ACCESS));
|
||||
status = NtCreateEvent (pevt, CYG_EVENT_ACCESS, &attr,
|
||||
NotificationEvent, FALSE);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
debug_printf ("NtCreateEvent: %p", status);
|
||||
return geterrno_from_win_error (RtlNtStatusToDosError (status));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -175,13 +195,13 @@ ipc_cond_timedwait (HANDLE evt, HANDLE mtx, const struct timespec *abstime)
|
|||
timeout = (abstime->tv_sec - tv.tv_sec) * 1000;
|
||||
timeout += (abstime->tv_nsec / 1000 - tv.tv_usec) / 1000;
|
||||
}
|
||||
ResetEvent (evt);
|
||||
if (ipc_mutex_unlock (mtx))
|
||||
return -1;
|
||||
switch (WaitForMultipleObjects (2, h, TRUE, timeout))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
case WAIT_ABANDONED_0:
|
||||
ResetEvent (evt);
|
||||
return 0;
|
||||
case WAIT_TIMEOUT:
|
||||
ipc_mutex_lock (mtx);
|
||||
|
@ -295,7 +315,8 @@ struct mq_info
|
|||
unsigned long mqi_magic; /* magic number if open */
|
||||
int mqi_flags; /* flags for this process */
|
||||
HANDLE mqi_lock; /* mutex lock */
|
||||
HANDLE mqi_wait; /* and condition variable */
|
||||
HANDLE mqi_waitsend; /* and condition variable for full queue */
|
||||
HANDLE mqi_waitrecv; /* and condition variable for empty queue */
|
||||
};
|
||||
|
||||
#define MQI_MAGIC 0x98765432UL
|
||||
|
@ -383,7 +404,7 @@ again:
|
|||
goto err;
|
||||
|
||||
/* Allocate one mq_info{} for the queue */
|
||||
if (!(mqinfo = (struct mq_info *) malloc (sizeof (struct mq_info))))
|
||||
if (!(mqinfo = (struct mq_info *) calloc (1, sizeof (struct mq_info))))
|
||||
goto err;
|
||||
mqinfo->mqi_hdr = mqhdr = (struct mq_hdr *) mptr;
|
||||
mqinfo->mqi_magic = MQI_MAGIC;
|
||||
|
@ -417,12 +438,16 @@ again:
|
|||
msghdr = (struct msg_hdr *) &mptr[index];
|
||||
msghdr->msg_next = 0; /* end of free list */
|
||||
|
||||
/* Initialize mutex & condition variable */
|
||||
/* Initialize mutex & condition variables */
|
||||
i = ipc_mutex_init (&mqinfo->mqi_lock, mqhdr->mqh_uname);
|
||||
if (i != 0)
|
||||
goto pthreaderr;
|
||||
|
||||
i = ipc_cond_init (&mqinfo->mqi_wait, mqhdr->mqh_uname);
|
||||
i = ipc_cond_init (&mqinfo->mqi_waitsend, mqhdr->mqh_uname, 'S');
|
||||
if (i != 0)
|
||||
goto pthreaderr;
|
||||
|
||||
i = ipc_cond_init (&mqinfo->mqi_waitrecv, mqhdr->mqh_uname, 'R');
|
||||
if (i != 0)
|
||||
goto pthreaderr;
|
||||
|
||||
|
@ -473,7 +498,7 @@ exists:
|
|||
fd = -1;
|
||||
|
||||
/* Allocate one mq_info{} for each open */
|
||||
if (!(mqinfo = (struct mq_info *) malloc (sizeof (struct mq_info))))
|
||||
if (!(mqinfo = (struct mq_info *) calloc (1, sizeof (struct mq_info))))
|
||||
goto err;
|
||||
mqinfo->mqi_hdr = mqhdr = (struct mq_hdr *) mptr;
|
||||
mqinfo->mqi_magic = MQI_MAGIC;
|
||||
|
@ -484,7 +509,11 @@ exists:
|
|||
if (i != 0)
|
||||
goto pthreaderr;
|
||||
|
||||
i = ipc_cond_init (&mqinfo->mqi_wait, mqhdr->mqh_uname);
|
||||
i = ipc_cond_init (&mqinfo->mqi_waitsend, mqhdr->mqh_uname, 'S');
|
||||
if (i != 0)
|
||||
goto pthreaderr;
|
||||
|
||||
i = ipc_cond_init (&mqinfo->mqi_waitrecv, mqhdr->mqh_uname, 'R');
|
||||
if (i != 0)
|
||||
goto pthreaderr;
|
||||
|
||||
|
@ -501,7 +530,15 @@ err:
|
|||
if (mptr != (int8_t *) MAP_FAILED)
|
||||
munmap((void *) mptr, (size_t) filesize);
|
||||
if (mqinfo)
|
||||
free (mqinfo);
|
||||
{
|
||||
if (mqinfo->mqi_lock)
|
||||
ipc_mutex_close (mqinfo->mqi_lock);
|
||||
if (mqinfo->mqi_waitsend)
|
||||
ipc_cond_close (mqinfo->mqi_waitsend);
|
||||
if (mqinfo->mqi_waitrecv)
|
||||
ipc_cond_close (mqinfo->mqi_waitrecv);
|
||||
free (mqinfo);
|
||||
}
|
||||
if (fd >= 0)
|
||||
close (fd);
|
||||
return (mqd_t) -1;
|
||||
|
@ -696,7 +733,7 @@ _mq_send (mqd_t mqd, const char *ptr, size_t len, unsigned int prio,
|
|||
}
|
||||
/* Wait for room for one message on the queue */
|
||||
while (attr->mq_curmsgs >= attr->mq_maxmsg)
|
||||
ipc_cond_timedwait (mqinfo->mqi_wait, mqinfo->mqi_lock, abstime);
|
||||
ipc_cond_timedwait (mqinfo->mqi_waitsend, mqinfo->mqi_lock, abstime);
|
||||
}
|
||||
|
||||
/* nmsghdr will point to new message */
|
||||
|
@ -732,7 +769,7 @@ _mq_send (mqd_t mqd, const char *ptr, size_t len, unsigned int prio,
|
|||
}
|
||||
/* Wake up anyone blocked in mq_receive waiting for a message */
|
||||
if (attr->mq_curmsgs == 0)
|
||||
ipc_cond_signal (mqinfo->mqi_wait);
|
||||
ipc_cond_signal (mqinfo->mqi_waitrecv);
|
||||
attr->mq_curmsgs++;
|
||||
|
||||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||
|
@ -803,7 +840,7 @@ _mq_receive (mqd_t mqd, char *ptr, size_t maxlen, unsigned int *priop,
|
|||
/* Wait for a message to be placed onto queue */
|
||||
mqhdr->mqh_nwait++;
|
||||
while (attr->mq_curmsgs == 0)
|
||||
ipc_cond_timedwait (mqinfo->mqi_wait, mqinfo->mqi_lock, abstime);
|
||||
ipc_cond_timedwait (mqinfo->mqi_waitrecv, mqinfo->mqi_lock, abstime);
|
||||
mqhdr->mqh_nwait--;
|
||||
}
|
||||
|
||||
|
@ -823,7 +860,7 @@ _mq_receive (mqd_t mqd, char *ptr, size_t maxlen, unsigned int *priop,
|
|||
|
||||
/* Wake up anyone blocked in mq_send waiting for room */
|
||||
if (attr->mq_curmsgs == attr->mq_maxmsg)
|
||||
ipc_cond_signal (mqinfo->mqi_wait);
|
||||
ipc_cond_signal (mqinfo->mqi_waitsend);
|
||||
attr->mq_curmsgs--;
|
||||
|
||||
ipc_mutex_unlock (mqinfo->mqi_lock);
|
||||
|
@ -878,7 +915,8 @@ mq_close (mqd_t mqd)
|
|||
return -1;
|
||||
|
||||
mqinfo->mqi_magic = 0; /* just in case */
|
||||
ipc_cond_close (mqinfo->mqi_wait);
|
||||
ipc_cond_close (mqinfo->mqi_waitsend);
|
||||
ipc_cond_close (mqinfo->mqi_waitrecv);
|
||||
ipc_mutex_close (mqinfo->mqi_lock);
|
||||
free (mqinfo);
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue