summaryrefslogtreecommitdiffstats
path: root/src/lib/net/SocketMultiplexer.h
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@ubuntu.com>2018-04-25 18:07:30 -0400
committerLibravatarUnit 193 <unit193@ubuntu.com>2018-04-25 18:07:30 -0400
commit9b1b081cfdb1c0fb6457278775e0823f8bc10f62 (patch)
treece8840148d8445055ba9e4f12263b2208f234c16 /src/lib/net/SocketMultiplexer.h
Import Upstream version 2.0.0+dfsgupstream/2.0.0+dfsg
Diffstat (limited to 'src/lib/net/SocketMultiplexer.h')
-rw-r--r--src/lib/net/SocketMultiplexer.h111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/lib/net/SocketMultiplexer.h b/src/lib/net/SocketMultiplexer.h
new file mode 100644
index 0000000..4aa39fc
--- /dev/null
+++ b/src/lib/net/SocketMultiplexer.h
@@ -0,0 +1,111 @@
+/*
+ * barrier -- mouse and keyboard sharing utility
+ * Copyright (C) 2012-2016 Symless Ltd.
+ * Copyright (C) 2004 Chris Schoeneman
+ *
+ * This package is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * found in the file LICENSE that should have accompanied this file.
+ *
+ * This package is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "arch/IArchNetwork.h"
+#include "common/stdlist.h"
+#include "common/stdmap.h"
+
+template <class T>
+class CondVar;
+class Mutex;
+class Thread;
+class ISocket;
+class ISocketMultiplexerJob;
+
+//! Socket multiplexer
+/*!
+A socket multiplexer services multiple sockets simultaneously.
+*/
+class SocketMultiplexer {
+public:
+ SocketMultiplexer();
+ ~SocketMultiplexer();
+
+ //! @name manipulators
+ //@{
+
+ void addSocket(ISocket*, ISocketMultiplexerJob*);
+
+ void removeSocket(ISocket*);
+
+ //@}
+ //! @name accessors
+ //@{
+
+ // maybe belongs on ISocketMultiplexer
+ static SocketMultiplexer*
+ getInstance();
+
+ //@}
+
+private:
+ // list of jobs. we use a list so we can safely iterate over it
+ // while other threads modify it.
+ typedef std::list<ISocketMultiplexerJob*> SocketJobs;
+ typedef SocketJobs::iterator JobCursor;
+ typedef std::map<ISocket*, JobCursor> SocketJobMap;
+
+ // service sockets. the service thread will only access m_sockets
+ // and m_update while m_pollable and m_polling are true. all other
+ // threads must only modify these when m_pollable and m_polling are
+ // false. only the service thread sets m_polling.
+ void serviceThread(void*);
+
+ // create, iterate, and destroy a cursor. a cursor is used to
+ // safely iterate through the job list while other threads modify
+ // the list. it works by inserting a dummy item in the list and
+ // moving that item through the list. the dummy item will never
+ // be removed by other edits so an iterator pointing at the item
+ // remains valid until we remove the dummy item in deleteCursor().
+ // nextCursor() finds the next non-dummy item, moves our dummy
+ // item just past it, and returns an iterator for the non-dummy
+ // item. all cursor calls lock the mutex for their duration.
+ JobCursor newCursor();
+ JobCursor nextCursor(JobCursor);
+ void deleteCursor(JobCursor);
+
+ // lock out locking the job list. this blocks if another thread
+ // has already locked out locking. once it returns, only the
+ // calling thread will be able to lock the job list after any
+ // current lock is released.
+ void lockJobListLock();
+
+ // lock the job list. this blocks if the job list is already
+ // locked. the calling thread must have called requestJobLock.
+ void lockJobList();
+
+ // unlock the job list and the lock out on locking.
+ void unlockJobList();
+
+private:
+ Mutex* m_mutex;
+ Thread* m_thread;
+ bool m_update;
+ CondVar<bool>* m_jobsReady;
+ CondVar<bool>* m_jobListLock;
+ CondVar<bool>* m_jobListLockLocked;
+ Thread* m_jobListLocker;
+ Thread* m_jobListLockLocker;
+
+ SocketJobs m_socketJobs;
+ SocketJobMap m_socketJobMap;
+ ISocketMultiplexerJob*
+ m_cursorMark;
+};