Cygwin: FIFO: simplify the listen_client_thread code
Always return 0; no one is doing anything with the return value anyway. Remove the return value from stop_listen_client. Make the connection event auto-reset, so that we don't have to reset it later. Simplify the process of connecting a bogus client when thread termination is signaled. Make some failures fatal. Remove the unnecessary extra check for thread termination near the end of listen_client_thread.
This commit is contained in:
parent
32dbc3d215
commit
9b2afd78ce
@ -1319,7 +1319,7 @@ class fhandler_fifo: public fhandler_base
|
|||||||
int add_client_handler ();
|
int add_client_handler ();
|
||||||
void delete_client_handler (int);
|
void delete_client_handler (int);
|
||||||
bool listen_client ();
|
bool listen_client ();
|
||||||
int stop_listen_client ();
|
void stop_listen_client ();
|
||||||
int check_listen_client_thread ();
|
int check_listen_client_thread ();
|
||||||
void record_connection (fifo_client_handler&,
|
void record_connection (fifo_client_handler&,
|
||||||
fifo_client_connect_state = fc_connected);
|
fifo_client_connect_state = fc_connected);
|
||||||
@ -1345,7 +1345,7 @@ public:
|
|||||||
ssize_t __reg3 raw_write (const void *ptr, size_t ulen);
|
ssize_t __reg3 raw_write (const void *ptr, size_t ulen);
|
||||||
bool arm (HANDLE h);
|
bool arm (HANDLE h);
|
||||||
bool need_fixup_before () const { return reader; }
|
bool need_fixup_before () const { return reader; }
|
||||||
int fixup_before_fork_exec (DWORD) { return stop_listen_client (); }
|
int fixup_before_fork_exec (DWORD) { stop_listen_client (); return 0; }
|
||||||
void init_fixup_before ();
|
void init_fixup_before ();
|
||||||
void fixup_after_fork (HANDLE);
|
void fixup_after_fork (HANDLE);
|
||||||
void fixup_after_exec ();
|
void fixup_after_exec ();
|
||||||
|
@ -324,11 +324,10 @@ fhandler_fifo::record_connection (fifo_client_handler& fc,
|
|||||||
DWORD
|
DWORD
|
||||||
fhandler_fifo::listen_client_thread ()
|
fhandler_fifo::listen_client_thread ()
|
||||||
{
|
{
|
||||||
DWORD ret = -1;
|
HANDLE conn_evt;
|
||||||
HANDLE evt;
|
|
||||||
|
|
||||||
if (!(evt = create_event ()))
|
if (!(conn_evt = CreateEvent (NULL, false, false, NULL)))
|
||||||
goto out;
|
api_fatal ("Can't create connection event, %E");
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -346,7 +345,7 @@ fhandler_fifo::listen_client_thread ()
|
|||||||
|
|
||||||
/* Create a new client handler. */
|
/* Create a new client handler. */
|
||||||
if (add_client_handler () < 0)
|
if (add_client_handler () < 0)
|
||||||
goto out;
|
api_fatal ("Can't add a client handler, %E");
|
||||||
|
|
||||||
/* Allow a writer to open. */
|
/* Allow a writer to open. */
|
||||||
if (!arm (read_ready))
|
if (!arm (read_ready))
|
||||||
@ -359,12 +358,13 @@ fhandler_fifo::listen_client_thread ()
|
|||||||
fifo_client_handler& fc = fc_handler[nhandlers - 1];
|
fifo_client_handler& fc = fc_handler[nhandlers - 1];
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
|
bool cancel = false;
|
||||||
|
|
||||||
status = NtFsControlFile (fc.h, evt, NULL, NULL, &io,
|
status = NtFsControlFile (fc.h, conn_evt, NULL, NULL, &io,
|
||||||
FSCTL_PIPE_LISTEN, NULL, 0, NULL, 0);
|
FSCTL_PIPE_LISTEN, NULL, 0, NULL, 0);
|
||||||
if (status == STATUS_PENDING)
|
if (status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
HANDLE w[2] = { evt, lct_termination_evt };
|
HANDLE w[2] = { conn_evt, lct_termination_evt };
|
||||||
DWORD waitret = WaitForMultipleObjects (2, w, false, INFINITE);
|
DWORD waitret = WaitForMultipleObjects (2, w, false, INFINITE);
|
||||||
switch (waitret)
|
switch (waitret)
|
||||||
{
|
{
|
||||||
@ -372,83 +372,65 @@ fhandler_fifo::listen_client_thread ()
|
|||||||
status = io.Status;
|
status = io.Status;
|
||||||
break;
|
break;
|
||||||
case WAIT_OBJECT_0 + 1:
|
case WAIT_OBJECT_0 + 1:
|
||||||
ret = 0;
|
|
||||||
status = STATUS_THREAD_IS_TERMINATING;
|
status = STATUS_THREAD_IS_TERMINATING;
|
||||||
|
cancel = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
__seterrno ();
|
api_fatal ("WFMO failed, %E");
|
||||||
debug_printf ("WaitForMultipleObjects failed, %E");
|
|
||||||
status = STATUS_THREAD_IS_TERMINATING;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HANDLE ph = NULL;
|
HANDLE ph = NULL;
|
||||||
int ps = -1;
|
NTSTATUS status1;
|
||||||
|
|
||||||
fifo_client_lock ();
|
fifo_client_lock ();
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case STATUS_SUCCESS:
|
case STATUS_SUCCESS:
|
||||||
case STATUS_PIPE_CONNECTED:
|
case STATUS_PIPE_CONNECTED:
|
||||||
record_connection (fc);
|
record_connection (fc);
|
||||||
ResetEvent (evt);
|
|
||||||
break;
|
break;
|
||||||
case STATUS_PIPE_CLOSING:
|
case STATUS_PIPE_CLOSING:
|
||||||
record_connection (fc, fc_closing);
|
record_connection (fc, fc_closing);
|
||||||
ResetEvent (evt);
|
|
||||||
break;
|
break;
|
||||||
case STATUS_THREAD_IS_TERMINATING:
|
case STATUS_THREAD_IS_TERMINATING:
|
||||||
/* Force NtFsControlFile to complete. Otherwise the next
|
/* Try to connect a bogus client. Otherwise fc is still
|
||||||
writer to connect might not be recorded in the client
|
listening, and the next connection might not get recorded. */
|
||||||
handler list. */
|
status1 = open_pipe (ph);
|
||||||
status = open_pipe (ph);
|
WaitForSingleObject (conn_evt, INFINITE);
|
||||||
if (NT_SUCCESS (status)
|
if (NT_SUCCESS (status1))
|
||||||
&& (NT_SUCCESS (io.Status) || io.Status == STATUS_PIPE_CONNECTED))
|
/* Bogus cilent connected. */
|
||||||
{
|
|
||||||
debug_printf ("successfully connected bogus client");
|
|
||||||
delete_client_handler (nhandlers - 1);
|
delete_client_handler (nhandlers - 1);
|
||||||
}
|
|
||||||
else if ((ps = fc.pipe_state ()) == FILE_PIPE_CONNECTED_STATE
|
|
||||||
|| ps == FILE_PIPE_INPUT_AVAILABLE_STATE)
|
|
||||||
{
|
|
||||||
/* A connection was made under our nose. */
|
|
||||||
debug_printf ("recording connection before terminating");
|
|
||||||
record_connection (fc);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
|
/* Did a real client connect? */
|
||||||
|
switch (io.Status)
|
||||||
{
|
{
|
||||||
debug_printf ("failed to terminate NtFsControlFile cleanly");
|
case STATUS_SUCCESS:
|
||||||
delete_client_handler (nhandlers - 1);
|
case STATUS_PIPE_CONNECTED:
|
||||||
ret = -1;
|
record_connection (fc);
|
||||||
|
break;
|
||||||
|
case STATUS_PIPE_CLOSING:
|
||||||
|
record_connection (fc, fc_closing);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
debug_printf ("NtFsControlFile status %y after failing to connect bogus client or real client", io.Status);
|
||||||
|
fc.state = fc_unknown;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fifo_client_unlock ();
|
||||||
if (ph)
|
if (ph)
|
||||||
NtClose (ph);
|
NtClose (ph);
|
||||||
fifo_client_unlock ();
|
if (cancel)
|
||||||
goto out;
|
goto out;
|
||||||
default:
|
|
||||||
debug_printf ("NtFsControlFile status %y", status);
|
|
||||||
__seterrno_from_nt_status (status);
|
|
||||||
delete_client_handler (nhandlers - 1);
|
|
||||||
fifo_client_unlock ();
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
fifo_client_unlock ();
|
|
||||||
/* Check for thread termination in case WaitForMultipleObjects
|
|
||||||
didn't get called above. */
|
|
||||||
if (IsEventSignalled (lct_termination_evt))
|
|
||||||
{
|
|
||||||
ret = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (evt)
|
if (conn_evt)
|
||||||
NtClose (evt);
|
NtClose (conn_evt);
|
||||||
ResetEvent (read_ready);
|
ResetEvent (read_ready);
|
||||||
if (ret < 0)
|
return 0;
|
||||||
debug_printf ("exiting with error, %E");
|
|
||||||
else
|
|
||||||
debug_printf ("exiting without error");
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -945,10 +927,9 @@ fifo_client_handler::pipe_state ()
|
|||||||
return fpli.NamedPipeState;
|
return fpli.NamedPipeState;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
fhandler_fifo::stop_listen_client ()
|
fhandler_fifo::stop_listen_client ()
|
||||||
{
|
{
|
||||||
int ret = 0;
|
|
||||||
HANDLE thr, evt;
|
HANDLE thr, evt;
|
||||||
|
|
||||||
thr = InterlockedExchangePointer (&listen_client_thr, NULL);
|
thr = InterlockedExchangePointer (&listen_client_thr, NULL);
|
||||||
@ -957,19 +938,11 @@ fhandler_fifo::stop_listen_client ()
|
|||||||
if (lct_termination_evt)
|
if (lct_termination_evt)
|
||||||
SetEvent (lct_termination_evt);
|
SetEvent (lct_termination_evt);
|
||||||
WaitForSingleObject (thr, INFINITE);
|
WaitForSingleObject (thr, INFINITE);
|
||||||
DWORD err;
|
|
||||||
GetExitCodeThread (thr, &err);
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
ret = -1;
|
|
||||||
debug_printf ("listen_client_thread exited with error");
|
|
||||||
}
|
|
||||||
NtClose (thr);
|
NtClose (thr);
|
||||||
}
|
}
|
||||||
evt = InterlockedExchangePointer (&lct_termination_evt, NULL);
|
evt = InterlockedExchangePointer (&lct_termination_evt, NULL);
|
||||||
if (evt)
|
if (evt)
|
||||||
NtClose (evt);
|
NtClose (evt);
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -978,7 +951,7 @@ fhandler_fifo::close ()
|
|||||||
/* Avoid deadlock with lct in case this is called from a signal
|
/* Avoid deadlock with lct in case this is called from a signal
|
||||||
handler or another thread. */
|
handler or another thread. */
|
||||||
fifo_client_unlock ();
|
fifo_client_unlock ();
|
||||||
int ret = stop_listen_client ();
|
stop_listen_client ();
|
||||||
if (read_ready)
|
if (read_ready)
|
||||||
NtClose (read_ready);
|
NtClose (read_ready);
|
||||||
if (write_ready)
|
if (write_ready)
|
||||||
@ -987,7 +960,7 @@ fhandler_fifo::close ()
|
|||||||
for (int i = 0; i < nhandlers; i++)
|
for (int i = 0; i < nhandlers; i++)
|
||||||
fc_handler[i].close ();
|
fc_handler[i].close ();
|
||||||
fifo_client_unlock ();
|
fifo_client_unlock ();
|
||||||
return fhandler_base::close () || ret;
|
return fhandler_base::close ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have a write handle (i.e., we're a duplexer or a writer),
|
/* If we have a write handle (i.e., we're a duplexer or a writer),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user