summaryrefslogtreecommitdiffstats
path: root/fnet
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2018-10-04 09:34:15 +0000
committerHåvard Pettersen <havardpe@oath.com>2018-10-04 09:34:15 +0000
commitf8196e6d27bc0b8d1c3fd29a9b04751410f0135e (patch)
tree439508e94715703daa93d3a5bead25bb9ccb6539 /fnet
parent250c09c530c00165f1956abe5d80aebe7042a2b5 (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.cpp11
-rw-r--r--fnet/src/vespa/fnet/transport_thread.h5
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