Cygwin: select: Introduce select_sem semaphore for pipe.

- This patch introduces select_sem semaphore which notifies pipe status
  change.
This commit is contained in:
Takashi Yano 2021-09-08 17:18:35 +09:00 committed by Corinna Vinschen
parent b07660ac19
commit 597f87294d
4 changed files with 37 additions and 2 deletions

View File

@ -1464,6 +1464,7 @@ fhandler_base::fhandler_base () :
_refcnt (0), _refcnt (0),
openflags (0), openflags (0),
unique_id (0), unique_id (0),
select_sem (NULL),
archetype (NULL), archetype (NULL),
usecount (0) usecount (0)
{ {

View File

@ -217,6 +217,7 @@ class fhandler_base
void set_ino (ino_t i) { ino = i; } void set_ino (ino_t i) { ino = i; }
HANDLE read_state; HANDLE read_state;
HANDLE select_sem;
public: public:
LONG inc_refcnt () {return InterlockedIncrement (&_refcnt);} LONG inc_refcnt () {return InterlockedIncrement (&_refcnt);}
@ -520,6 +521,8 @@ public:
fh->copy_from (this); fh->copy_from (this);
return fh; return fh;
} }
HANDLE get_select_sem () { return select_sem; }
}; };
struct wsa_event struct wsa_event

View File

@ -376,6 +376,8 @@ fhandler_pipe::raw_read (void *ptr, size_t& len)
} }
else if (status == STATUS_THREAD_CANCELED) else if (status == STATUS_THREAD_CANCELED)
pthread::static_cancel_self (); pthread::static_cancel_self ();
if (select_sem && nbytes)
ReleaseSemaphore (select_sem, get_obj_handle_count (select_sem), NULL);
len = nbytes; len = nbytes;
} }
@ -507,6 +509,8 @@ fhandler_pipe_fifo::raw_write (const void *ptr, size_t len)
set_errno (EINTR); set_errno (EINTR);
else if (status == STATUS_THREAD_CANCELED) else if (status == STATUS_THREAD_CANCELED)
pthread::static_cancel_self (); pthread::static_cancel_self ();
if (select_sem && nbytes)
ReleaseSemaphore (select_sem, get_obj_handle_count (select_sem), NULL);
return nbytes ?: -1; return nbytes ?: -1;
} }
@ -515,6 +519,8 @@ fhandler_pipe::fixup_after_fork (HANDLE parent)
{ {
if (read_mtx) if (read_mtx)
fork_fixup (parent, read_mtx, "read_mtx"); fork_fixup (parent, read_mtx, "read_mtx");
if (select_sem)
fork_fixup (parent, select_sem, "select_sem");
fhandler_base::fixup_after_fork (parent); fhandler_base::fixup_after_fork (parent);
} }
@ -536,6 +542,15 @@ fhandler_pipe::dup (fhandler_base *child, int flags)
ftp->close (); ftp->close ();
res = -1; res = -1;
} }
else if (select_sem &&
!DuplicateHandle (GetCurrentProcess (), select_sem,
GetCurrentProcess (), &ftp->select_sem,
0, !(flags & O_CLOEXEC), DUPLICATE_SAME_ACCESS))
{
__seterrno ();
ftp->close ();
res = -1;
}
debug_printf ("res %d", res); debug_printf ("res %d", res);
return res; return res;
@ -546,6 +561,11 @@ fhandler_pipe::close ()
{ {
if (read_mtx) if (read_mtx)
CloseHandle (read_mtx); CloseHandle (read_mtx);
if (select_sem)
{
ReleaseSemaphore (select_sem, get_obj_handle_count (select_sem), NULL);
CloseHandle (select_sem);
}
return fhandler_base::close (); return fhandler_base::close ();
} }
@ -765,6 +785,11 @@ fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode)
fhs[0]->set_read_mutex (mtx); fhs[0]->set_read_mutex (mtx);
res = 0; res = 0;
} }
fhs[0]->select_sem = CreateSemaphore (&sa, 0, INT32_MAX, NULL);
if (fhs[0]->select_sem)
DuplicateHandle (GetCurrentProcess (), fhs[0]->select_sem,
GetCurrentProcess (), &fhs[1]->select_sem,
0, 1, DUPLICATE_SAME_ACCESS);
} }
debug_printf ("%R = pipe([%p, %p], %d, %y)", res, fhs[0], fhs[1], psize, mode); debug_printf ("%R = pipe([%p, %p], %d, %y)", res, fhs[0], fhs[1], psize, mode);

View File

@ -762,7 +762,13 @@ start_thread_pipe (select_record *me, select_stuff *stuff)
{ {
pi->start = &stuff->start; pi->start = &stuff->start;
pi->stop_thread = false; pi->stop_thread = false;
pi->bye = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); pi->bye = me->fh->get_select_sem ();
if (pi->bye)
DuplicateHandle (GetCurrentProcess (), pi->bye,
GetCurrentProcess (), &pi->bye,
0, 0, DUPLICATE_SAME_ACCESS);
else
pi->bye = CreateSemaphore (&sec_none_nih, 0, INT32_MAX, NULL);
pi->thread = new cygthread (thread_pipe, pi, "pipesel"); pi->thread = new cygthread (thread_pipe, pi, "pipesel");
me->h = *pi->thread; me->h = *pi->thread;
if (!me->h) if (!me->h)
@ -780,7 +786,7 @@ pipe_cleanup (select_record *, select_stuff *stuff)
if (pi->thread) if (pi->thread)
{ {
pi->stop_thread = true; pi->stop_thread = true;
SetEvent (pi->bye); ReleaseSemaphore (pi->bye, get_obj_handle_count (pi->bye), NULL);
pi->thread->detach (); pi->thread->detach ();
CloseHandle (pi->bye); CloseHandle (pi->bye);
} }