diff options
author | Håvard Pettersen <havardpe@oath.com> | 2018-10-04 09:34:15 +0000 |
---|---|---|
committer | Håvard Pettersen <havardpe@oath.com> | 2018-10-04 09:34:15 +0000 |
commit | f8196e6d27bc0b8d1c3fd29a9b04751410f0135e (patch) | |
tree | 439508e94715703daa93d3a5bead25bb9ccb6539 /fnet | |
parent | 250c09c530c00165f1956abe5d80aebe7042a2b5 (diff) |
introduce pseudo-thread mutex
used to emulate single-threaded behavior after the thread itself has
shut down.
Diffstat (limited to 'fnet')
-rw-r--r-- | fnet/src/vespa/fnet/transport_thread.cpp | 11 | ||||
-rw-r--r-- | fnet/src/vespa/fnet/transport_thread.h | 5 |
2 files changed, 14 insertions, 2 deletions
diff --git a/fnet/src/vespa/fnet/transport_thread.cpp b/fnet/src/vespa/fnet/transport_thread.cpp index 2c0d00b22f3..9e7a34209b4 100644 --- a/fnet/src/vespa/fnet/transport_thread.cpp +++ b/fnet/src/vespa/fnet/transport_thread.cpp @@ -118,7 +118,7 @@ FNET_TransportThread::PostEvent(FNET_ControlPacket *cpacket, std::unique_lock<std::mutex> guard(_lock); if (_shutdown) { guard.unlock(); - DiscardEvent(cpacket, context); + SafeDiscardEvent(cpacket, context); return false; } wasEmpty = _queue.IsEmpty_NoLock(); @@ -150,6 +150,14 @@ FNET_TransportThread::DiscardEvent(FNET_ControlPacket *cpacket, } } +void +FNET_TransportThread::SafeDiscardEvent(FNET_ControlPacket *cpacket, + FNET_Context context) +{ + WaitFinished(); // make sure actual thread is all done + std::lock_guard guard(_pseudo_thread); // be the thread + DiscardEvent(cpacket, context); +} void FNET_TransportThread::handle_add_cmd(FNET_IOComponent *ioc) @@ -215,6 +223,7 @@ FNET_TransportThread::FNET_TransportThread(FNET_Transport &owner_in) _myQueue(), _lock(), _cond(), + _pseudo_thread(), _started(false), _shutdown(false), _finished(false), diff --git a/fnet/src/vespa/fnet/transport_thread.h b/fnet/src/vespa/fnet/transport_thread.h index 408d20619d2..4de82d802dd 100644 --- a/fnet/src/vespa/fnet/transport_thread.h +++ b/fnet/src/vespa/fnet/transport_thread.h @@ -46,13 +46,13 @@ private: FNET_PacketQueue_NoLock _myQueue; // inner event queue std::mutex _lock; // used for synchronization std::condition_variable _cond; // used for synchronization + std::recursive_mutex _pseudo_thread; // used after transport thread has shut down bool _started; // event loop started ? bool _shutdown; // should stop event loop ? bool _finished; // event loop stopped ? bool _waitFinished; // someone is waiting for _finished bool _deleted; // destructor called ? - FNET_TransportThread(const FNET_TransportThread &); FNET_TransportThread &operator=(const FNET_TransportThread &); @@ -133,6 +133,9 @@ private: **/ void DiscardEvent(FNET_ControlPacket *cpacket, FNET_Context context); + // safely discard events using the pseudo thread mutex + void SafeDiscardEvent(FNET_ControlPacket *cpacket, FNET_Context context); + /** * Obtain a reference to the object holding the configuration for |