Merge pull request #1352 from p12tic/cleanup-callbacks

Cleanup internal callback APIs
This commit is contained in:
Povilas Kanapickas 2021-11-01 17:28:53 +02:00 committed by GitHub
commit fc6d4e41d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 159 additions and 531 deletions

View File

@ -19,6 +19,7 @@
#pragma once #pragma once
#include "common/IInterface.h" #include "common/IInterface.h"
#include <functional>
/*! /*!
\class ArchCondImpl \class ArchCondImpl
@ -71,7 +72,7 @@ barrier. Each architecture must implement this interface.
class IArchMultithread : public IInterface { class IArchMultithread : public IInterface {
public: public:
//! Type of thread entry point //! Type of thread entry point
typedef void* (*ThreadFunc)(void*); typedef void (*ThreadFunc)(void*);
//! Type of thread identifier //! Type of thread identifier
typedef unsigned int ThreadID; typedef unsigned int ThreadID;
//! Types of signals //! Types of signals
@ -160,7 +161,7 @@ public:
Creates and starts a new thread, using \c func as the entry point Creates and starts a new thread, using \c func as the entry point
and passing it \c userData. The thread is an opaque data type. and passing it \c userData. The thread is an opaque data type.
*/ */
virtual ArchThread newThread(ThreadFunc func, void* userData) = 0; virtual ArchThread newThread(const std::function<void()>& func) = 0;
//! Get a reference to the calling thread //! Get a reference to the calling thread
/*! /*!
@ -235,15 +236,6 @@ public:
*/ */
virtual bool isExitedThread(ArchThread thread) = 0; virtual bool isExitedThread(ArchThread thread) = 0;
//! Returns the exit code of a thread
/*!
Waits indefinitely for \c thread to exit (if it hasn't yet) then
returns the thread's exit code.
(Cancellation point)
*/
virtual void* getResultOfThread(ArchThread thread) = 0;
//! Returns an ID for a thread //! Returns an ID for a thread
/*! /*!
Returns some ID number for \c thread. This is for logging purposes. Returns some ID number for \c thread. This is for logging purposes.

View File

@ -59,24 +59,19 @@ public:
int m_refCount; int m_refCount;
IArchMultithread::ThreadID m_id; IArchMultithread::ThreadID m_id;
pthread_t m_thread; pthread_t m_thread;
IArchMultithread::ThreadFunc m_func; std::function<void()> func_;;
void* m_userData;
bool m_cancel; bool m_cancel;
bool m_cancelling; bool m_cancelling;
bool m_exited; bool m_exited;
void* m_result;
void* m_networkData; void* m_networkData;
}; };
ArchThreadImpl::ArchThreadImpl() : ArchThreadImpl::ArchThreadImpl() :
m_refCount(1), m_refCount(1),
m_id(0), m_id(0),
m_func(NULL),
m_userData(NULL),
m_cancel(false), m_cancel(false),
m_cancelling(false), m_cancelling(false),
m_exited(false), m_exited(false),
m_result(NULL),
m_networkData(NULL) m_networkData(NULL)
{ {
// do nothing // do nothing
@ -319,11 +314,8 @@ ArchMultithreadPosix::unlockMutex(ArchMutex mutex)
} }
} }
ArchThread ArchThread ArchMultithreadPosix::newThread(const std::function<void()>& func)
ArchMultithreadPosix::newThread(ThreadFunc func, void* data)
{ {
assert(func != NULL);
// initialize signal handler. we do this here instead of the // initialize signal handler. we do this here instead of the
// constructor so we can avoid daemonizing (using fork()) // constructor so we can avoid daemonizing (using fork())
// when there are multiple threads. clients can safely // when there are multiple threads. clients can safely
@ -341,8 +333,7 @@ ArchMultithreadPosix::newThread(ThreadFunc func, void* data)
// create thread impl for new thread // create thread impl for new thread
ArchThreadImpl* thread = new ArchThreadImpl; ArchThreadImpl* thread = new ArchThreadImpl;
thread->m_func = func; thread->func_ = func;
thread->m_userData = data;
// create the thread. pthread_create() on RedHat 7.2 smp fails // create the thread. pthread_create() on RedHat 7.2 smp fails
// if passed a NULL attr so use a default attr. // if passed a NULL attr so use a default attr.
@ -389,7 +380,7 @@ ArchMultithreadPosix::closeThread(ArchThread thread)
// decrement ref count and clean up thread if no more references // decrement ref count and clean up thread if no more references
if (--thread->m_refCount == 0) { if (--thread->m_refCount == 0) {
// detach from thread (unless it's the main thread) // detach from thread (unless it's the main thread)
if (thread->m_func != NULL) { if (thread->func_) {
pthread_detach(thread->m_thread); pthread_detach(thread->m_thread);
} }
@ -526,13 +517,6 @@ ArchMultithreadPosix::isExitedThread(ArchThread thread)
return thread->m_exited; return thread->m_exited;
} }
void*
ArchMultithreadPosix::getResultOfThread(ArchThread thread)
{
std::lock_guard<std::mutex> lock(m_threadMutex);
return thread->m_result;
}
IArchMultithread::ThreadID IArchMultithread::ThreadID
ArchMultithreadPosix::getIDOfThread(ArchThread thread) ArchMultithreadPosix::getIDOfThread(ArchThread thread)
{ {
@ -699,10 +683,8 @@ ArchMultithreadPosix::doThreadFunc(ArchThread thread)
std::lock_guard<std::mutex> lock(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
} }
void* result = NULL;
try { try {
// go thread->func_();
result = (*thread->m_func)(thread->m_userData);
} }
catch (XThreadCancel&) { catch (XThreadCancel&) {
@ -721,7 +703,6 @@ ArchMultithreadPosix::doThreadFunc(ArchThread thread)
// thread has exited // thread has exited
{ {
std::lock_guard<std::mutex> lock(m_threadMutex); std::lock_guard<std::mutex> lock(m_threadMutex);
thread->m_result = result;
thread->m_exited = true; thread->m_exited = true;
} }

View File

@ -67,7 +67,7 @@ public:
virtual void closeMutex(ArchMutex); virtual void closeMutex(ArchMutex);
virtual void lockMutex(ArchMutex); virtual void lockMutex(ArchMutex);
virtual void unlockMutex(ArchMutex); virtual void unlockMutex(ArchMutex);
virtual ArchThread newThread(ThreadFunc, void*); virtual ArchThread newThread(const std::function<void()>& func);
virtual ArchThread newCurrentThread(); virtual ArchThread newCurrentThread();
virtual ArchThread copyThread(ArchThread); virtual ArchThread copyThread(ArchThread);
virtual void closeThread(ArchThread); virtual void closeThread(ArchThread);
@ -77,7 +77,6 @@ public:
virtual bool wait(ArchThread, double timeout); virtual bool wait(ArchThread, double timeout);
virtual bool isSameThread(ArchThread, ArchThread); virtual bool isSameThread(ArchThread, ArchThread);
virtual bool isExitedThread(ArchThread); virtual bool isExitedThread(ArchThread);
virtual void* getResultOfThread(ArchThread);
virtual ThreadID getIDOfThread(ArchThread); virtual ThreadID getIDOfThread(ArchThread);
virtual void setSignalHandler(ESignal, SignalFunc, void*); virtual void setSignalHandler(ESignal, SignalFunc, void*);
virtual void raiseSignal(ESignal); virtual void raiseSignal(ESignal);

View File

@ -49,12 +49,10 @@ public:
int m_refCount; int m_refCount;
HANDLE m_thread; HANDLE m_thread;
DWORD m_id; DWORD m_id;
IArchMultithread::ThreadFunc m_func; std::function<void()> func_;
void* m_userData;
HANDLE m_cancel; HANDLE m_cancel;
bool m_cancelling; bool m_cancelling;
HANDLE m_exit; HANDLE m_exit;
void* m_result;
void* m_networkData; void* m_networkData;
}; };
@ -62,10 +60,7 @@ ArchThreadImpl::ArchThreadImpl() :
m_refCount(1), m_refCount(1),
m_thread(NULL), m_thread(NULL),
m_id(0), m_id(0),
m_func(NULL),
m_userData(NULL),
m_cancelling(false), m_cancelling(false),
m_result(NULL),
m_networkData(NULL) m_networkData(NULL)
{ {
m_exit = CreateEvent(NULL, TRUE, FALSE, NULL); m_exit = CreateEvent(NULL, TRUE, FALSE, NULL);
@ -292,15 +287,13 @@ ArchMultithreadWindows::unlockMutex(ArchMutex mutex)
LeaveCriticalSection(&mutex->m_mutex); LeaveCriticalSection(&mutex->m_mutex);
} }
ArchThread ArchThread ArchMultithreadWindows::newThread(const std::function<void()>& func)
ArchMultithreadWindows::newThread(ThreadFunc func, void* data)
{ {
lockMutex(m_threadMutex); lockMutex(m_threadMutex);
// create thread impl for new thread // create thread impl for new thread
ArchThreadImpl* thread = new ArchThreadImpl; ArchThreadImpl* thread = new ArchThreadImpl;
thread->m_func = func; thread->func_ = func;
thread->m_userData = data;
// create thread // create thread
unsigned int id = 0; unsigned int id = 0;
@ -523,15 +516,6 @@ ArchMultithreadWindows::isExitedThread(ArchThread thread)
return (WaitForSingleObject(thread->m_exit, 0) == WAIT_OBJECT_0); return (WaitForSingleObject(thread->m_exit, 0) == WAIT_OBJECT_0);
} }
void*
ArchMultithreadWindows::getResultOfThread(ArchThread thread)
{
lockMutex(m_threadMutex);
void* result = thread->m_result;
unlockMutex(m_threadMutex);
return result;
}
IArchMultithread::ThreadID IArchMultithread::ThreadID
ArchMultithreadWindows::getIDOfThread(ArchThread thread) ArchMultithreadWindows::getIDOfThread(ArchThread thread)
{ {
@ -678,10 +662,8 @@ ArchMultithreadWindows::doThreadFunc(ArchThread thread)
lockMutex(m_threadMutex); lockMutex(m_threadMutex);
unlockMutex(m_threadMutex); unlockMutex(m_threadMutex);
void* result = NULL;
try { try {
// go thread->func_();
result = (*thread->m_func)(thread->m_userData);
} }
catch (XThreadCancel&) { catch (XThreadCancel&) {
@ -695,9 +677,6 @@ ArchMultithreadWindows::doThreadFunc(ArchThread thread)
} }
// thread has exited // thread has exited
lockMutex(m_threadMutex);
thread->m_result = result;
unlockMutex(m_threadMutex);
SetEvent(thread->m_exit); SetEvent(thread->m_exit);
// done with thread // done with thread

View File

@ -73,7 +73,7 @@ public:
virtual void closeMutex(ArchMutex); virtual void closeMutex(ArchMutex);
virtual void lockMutex(ArchMutex); virtual void lockMutex(ArchMutex);
virtual void unlockMutex(ArchMutex); virtual void unlockMutex(ArchMutex);
virtual ArchThread newThread(ThreadFunc, void*); virtual ArchThread newThread(const std::function<void()>& func);
virtual ArchThread newCurrentThread(); virtual ArchThread newCurrentThread();
virtual ArchThread copyThread(ArchThread); virtual ArchThread copyThread(ArchThread);
virtual void closeThread(ArchThread); virtual void closeThread(ArchThread);
@ -83,7 +83,6 @@ public:
virtual bool wait(ArchThread, double timeout); virtual bool wait(ArchThread, double timeout);
virtual bool isSameThread(ArchThread, ArchThread); virtual bool isSameThread(ArchThread, ArchThread);
virtual bool isExitedThread(ArchThread); virtual bool isExitedThread(ArchThread);
virtual void* getResultOfThread(ArchThread);
virtual ThreadID getIDOfThread(ArchThread); virtual ThreadID getIDOfThread(ArchThread);
virtual void setSignalHandler(ESignal, SignalFunc, void*); virtual void setSignalHandler(ESignal, SignalFunc, void*);
virtual void raiseSignal(ESignal); virtual void raiseSignal(ESignal);

View File

@ -88,7 +88,7 @@ ArchTaskBarWindows::init()
// create a window on the current desktop with the current // create a window on the current desktop with the current
// thread then the current thread won't be able to switch // thread then the current thread won't be able to switch
// desktops if it needs to. // desktops if it needs to.
m_thread = ARCH->newThread(&ArchTaskBarWindows::threadEntry, this); m_thread = ARCH->newThread([this]() { threadMainLoop(); });
// wait for child thread // wait for child thread
while (!m_ready) { while (!m_ready) {
@ -501,13 +501,6 @@ ArchTaskBarWindows::threadMainLoop()
UnregisterClass(className, instanceWin32()); UnregisterClass(className, instanceWin32());
} }
void*
ArchTaskBarWindows::threadEntry(void* self)
{
static_cast<ArchTaskBarWindows*>(self)->threadMainLoop();
return NULL;
}
HINSTANCE ArchTaskBarWindows::instanceWin32() HINSTANCE ArchTaskBarWindows::instanceWin32()
{ {
return ArchMiscWindows::instanceWin32(); return ArchMiscWindows::instanceWin32();

View File

@ -84,7 +84,6 @@ private:
static LRESULT CALLBACK static LRESULT CALLBACK
staticWndProc(HWND, UINT, WPARAM, LPARAM); staticWndProc(HWND, UINT, WPARAM, LPARAM);
void threadMainLoop(); void threadMainLoop();
static void* threadEntry(void*);
HINSTANCE instanceWin32(); HINSTANCE instanceWin32();

View File

@ -34,7 +34,6 @@
#if SYSAPI_WIN32 #if SYSAPI_WIN32
#include "base/IEventQueue.h" #include "base/IEventQueue.h"
#include "base/TMethodJob.h"
#endif #endif
#include <iostream> #include <iostream>
@ -229,8 +228,7 @@ App::handleIpcMessage(const Event& e, void*)
} }
} }
void void App::run_events_loop()
App::runEventsLoop(void*)
{ {
m_events->loop(); m_events->loop();

View File

@ -108,7 +108,7 @@ private:
protected: protected:
void initIpcClient(); void initIpcClient();
void cleanupIpcClient(); void cleanupIpcClient();
void runEventsLoop(void*); void run_events_loop();
IArchTaskBarReceiver* m_taskBarReceiver; IArchTaskBarReceiver* m_taskBarReceiver;
bool m_suspended; bool m_suspended;

View File

@ -37,7 +37,6 @@
#include "base/TMethodEventJob.h" #include "base/TMethodEventJob.h"
#include "base/log_outputters.h" #include "base/log_outputters.h"
#include "base/EventQueue.h" #include "base/EventQueue.h"
#include "base/TMethodJob.h"
#include "base/Log.h" #include "base/Log.h"
#include "common/Version.h" #include "common/Version.h"
@ -465,10 +464,7 @@ ClientApp::mainLoop()
#if defined(MAC_OS_X_VERSION_10_7) #if defined(MAC_OS_X_VERSION_10_7)
Thread thread( Thread thread([this](){ run_events_loop(); });
new TMethodJob<ClientApp>(
this, &ClientApp::runEventsLoop,
NULL));
// wait until carbon loop is ready // wait until carbon loop is ready
OSXScreen* screen = dynamic_cast<OSXScreen*>( OSXScreen* screen = dynamic_cast<OSXScreen*>(

View File

@ -24,7 +24,6 @@ namespace barrier { class Screen; }
class Event; class Event;
class Client; class Client;
class NetworkAddress; class NetworkAddress;
class Thread;
class ClientArgs; class ClientArgs;
class ClientApp : public App { class ClientApp : public App {

View File

@ -34,7 +34,6 @@
#include "base/EventQueue.h" #include "base/EventQueue.h"
#include "base/log_outputters.h" #include "base/log_outputters.h"
#include "base/FunctionEventJob.h" #include "base/FunctionEventJob.h"
#include "base/TMethodJob.h"
#include "base/IEventQueue.h" #include "base/IEventQueue.h"
#include "base/Log.h" #include "base/Log.h"
#include "base/TMethodEventJob.h" #include "base/TMethodEventJob.h"
@ -797,10 +796,7 @@ ServerApp::mainLoop()
#if defined(MAC_OS_X_VERSION_10_7) #if defined(MAC_OS_X_VERSION_10_7)
Thread thread( Thread thread([this](){ run_events_loop(); });
new TMethodJob<ServerApp>(
this, &ServerApp::runEventsLoop,
NULL));
// wait until carbon loop is ready // wait until carbon loop is ready
OSXScreen* screen = dynamic_cast<OSXScreen*>( OSXScreen* screen = dynamic_cast<OSXScreen*>(

View File

@ -42,14 +42,13 @@ bool StreamChunker::s_interruptFile = false;
Mutex* StreamChunker::s_interruptMutex = NULL; Mutex* StreamChunker::s_interruptMutex = NULL;
void void
StreamChunker::sendFile( StreamChunker::sendFile(const char* filename,
char* filename,
IEventQueue* events, IEventQueue* events,
void* eventTarget) void* eventTarget)
{ {
s_isChunkingFile = true; s_isChunkingFile = true;
std::fstream file(static_cast<char*>(filename), std::ios::in | std::ios::binary); std::fstream file(filename, std::ios::in | std::ios::binary);
if (!file.is_open()) { if (!file.is_open()) {
throw runtime_error("failed to open file"); throw runtime_error("failed to open file");

View File

@ -25,10 +25,7 @@ class Mutex;
class StreamChunker { class StreamChunker {
public: public:
static void sendFile( static void sendFile(const char* filename, IEventQueue* events, void* eventTarget);
char* filename,
IEventQueue* events,
void* eventTarget);
static void sendClipboard( static void sendClipboard(
String& data, String& data,
size_t size, size_t size,

View File

@ -28,7 +28,6 @@
#include "net/SocketMultiplexer.h" #include "net/SocketMultiplexer.h"
#include "arch/XArch.h" #include "arch/XArch.h"
#include "base/Log.h" #include "base/Log.h"
#include "base/TMethodJob.h"
#include "base/TMethodEventJob.h" #include "base/TMethodEventJob.h"
#include "base/EventQueue.h" #include "base/EventQueue.h"
#include "base/log_outputters.h" #include "base/log_outputters.h"

View File

@ -1,43 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 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/>.
*/
#include "base/FunctionJob.h"
//
// FunctionJob
//
FunctionJob::FunctionJob(void (*func)(void*), void* arg) :
m_func(func),
m_arg(arg)
{
// do nothing
}
FunctionJob::~FunctionJob()
{
// do nothing
}
void
FunctionJob::run()
{
if (m_func != NULL) {
m_func(m_arg);
}
}

View File

@ -1,39 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 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 "base/IJob.h"
//! Use a function as a job
/*!
A job class that invokes a function.
*/
class FunctionJob : public IJob {
public:
//! run() invokes \c func(arg)
FunctionJob(void (*func)(void*), void* arg = NULL);
virtual ~FunctionJob();
// IJob overrides
virtual void run();
private:
void (*m_func)(void*);
void* m_arg;
};

View File

@ -1,68 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 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 "IJob.h"
//! Use a function as a job
/*!
A job class that invokes a member function.
*/
template <class T>
class TMethodJob : public IJob {
public:
//! run() invokes \c object->method(arg)
TMethodJob(T* object, void (T::*method)(void*), void* arg = NULL);
virtual ~TMethodJob();
// IJob overrides
virtual void run();
private:
T* m_object;
void (T::*m_method)(void*);
void* m_arg;
};
template <class T>
inline
TMethodJob<T>::TMethodJob(T* object, void (T::*method)(void*), void* arg) :
m_object(object),
m_method(method),
m_arg(arg)
{
// do nothing
}
template <class T>
inline
TMethodJob<T>::~TMethodJob()
{
// do nothing
}
template <class T>
inline
void
TMethodJob<T>::run()
{
if (m_object != NULL) {
(m_object->*m_method)(m_arg);
}
}

View File

@ -17,7 +17,6 @@
*/ */
#include "base/log_outputters.h" #include "base/log_outputters.h"
#include "base/TMethodJob.h"
#include "arch/Arch.h" #include "arch/Arch.h"
#include "base/String.h" #include "base/String.h"
#include "io/filesystem.h" #include "io/filesystem.h"

View File

@ -37,7 +37,6 @@
#include "base/Log.h" #include "base/Log.h"
#include "base/IEventQueue.h" #include "base/IEventQueue.h"
#include "base/TMethodEventJob.h" #include "base/TMethodEventJob.h"
#include "base/TMethodJob.h"
#include <cstring> #include <cstring>
#include <cstdlib> #include <cstdlib>
@ -760,9 +759,7 @@ void
Client::onFileRecieveCompleted() Client::onFileRecieveCompleted()
{ {
if (isReceivedFileSizeValid()) { if (isReceivedFileSizeValid()) {
m_writeToDropDirThread = new Thread( m_writeToDropDirThread = new Thread([this](){ write_to_drop_dir_thread(); });
new TMethodJob<Client>(
this, &Client::writeToDropDirThread));
} }
} }
@ -772,8 +769,7 @@ Client::handleStopRetry(const Event&, void*)
m_args.m_restartable = false; m_args.m_restartable = false;
} }
void void Client::write_to_drop_dir_thread()
Client::writeToDropDirThread(void*)
{ {
LOG((CLOG_DEBUG "starting write to drop dir thread")); LOG((CLOG_DEBUG "starting write to drop dir thread"));
@ -812,18 +808,13 @@ Client::sendFileToServer(const char* filename)
StreamChunker::interruptFile(); StreamChunker::interruptFile();
} }
m_sendFileThread = new Thread( m_sendFileThread = new Thread([this, filename]() { send_file_thread(filename); });
new TMethodJob<Client>(
this, &Client::sendFileThread,
static_cast<void*>(const_cast<char*>(filename))));
} }
void void Client::send_file_thread(const char* filename)
Client::sendFileThread(void* filename)
{ {
try { try {
char* name = static_cast<char*>(filename); StreamChunker::sendFile(filename, m_events, this);
StreamChunker::sendFile(name, m_events, this);
} }
catch (std::runtime_error& error) { catch (std::runtime_error& error) {
LOG((CLOG_ERR "failed sending file chunks: %s", error.what())); LOG((CLOG_ERR "failed sending file chunks: %s", error.what()));

View File

@ -167,8 +167,8 @@ private:
void sendEvent(Event::Type, void*); void sendEvent(Event::Type, void*);
void sendConnectionFailedEvent(const char* msg); void sendConnectionFailedEvent(const char* msg);
void sendFileChunk(const void* data); void sendFileChunk(const void* data);
void sendFileThread(void*); void send_file_thread(const char* filename);
void writeToDropDirThread(void*); void write_to_drop_dir_thread();
void setupConnecting(); void setupConnecting();
void setupConnection(); void setupConnection();
void setupScreen(); void setupScreen();

View File

@ -28,7 +28,6 @@
#include "base/Event.h" #include "base/Event.h"
#include "base/EventQueue.h" #include "base/EventQueue.h"
#include "base/TMethodEventJob.h" #include "base/TMethodEventJob.h"
#include "base/TMethodJob.h"
enum EIpcLogOutputter { enum EIpcLogOutputter {
kBufferMaxSize = 1000, kBufferMaxSize = 1000,
@ -54,8 +53,7 @@ IpcLogOutputter::IpcLogOutputter(IpcServer& ipcServer, EIpcClientType clientType
m_clientType(clientType) m_clientType(clientType)
{ {
if (useThread) { if (useThread) {
m_bufferThread = new Thread(new TMethodJob<IpcLogOutputter>( m_bufferThread = new Thread([this](){ buffer_thread(); });
this, &IpcLogOutputter::bufferThread));
} }
} }
@ -142,8 +140,7 @@ IpcLogOutputter::isRunning()
return m_running; return m_running;
} }
void void IpcLogOutputter::buffer_thread()
IpcLogOutputter::bufferThread(void*)
{ {
m_bufferThreadId = m_bufferThread->getID(); m_bufferThreadId = m_bufferThread->getID();
m_running = true; m_running = true;

View File

@ -92,7 +92,7 @@ public:
private: private:
void init(); void init();
void bufferThread(void*); void buffer_thread();
std::string getChunk(size_t count); std::string getChunk(size_t count);
void appendBuffer(const std::string& text); void appendBuffer(const std::string& text);
bool isRunning(); bool isRunning();

View File

@ -28,12 +28,10 @@
// Thread // Thread
// //
Thread::Thread(IJob* job) Thread::Thread(const std::function<void()>& fun)
{ {
m_thread = ARCH->newThread(&Thread::threadFunc, job); m_thread = ARCH->newThread([=](){ threadFunc(fun); });
if (m_thread == NULL) { if (m_thread == NULL) {
// couldn't create thread
delete job;
throw XMTThreadUnavailable(); throw XMTThreadUnavailable();
} }
} }
@ -69,7 +67,7 @@ Thread::operator=(const Thread& thread)
void void
Thread::exit(void* result) Thread::exit(void* result)
{ {
throw XThreadExit(result); throw XThreadExit();
} }
void void
@ -108,15 +106,6 @@ Thread::wait(double timeout) const
return ARCH->wait(m_thread, timeout); return ARCH->wait(m_thread, timeout);
} }
void*
Thread::getResult() const
{
if (wait())
return ARCH->getResultOfThread(m_thread);
else
return NULL;
}
IArchMultithread::ThreadID IArchMultithread::ThreadID
Thread::getID() const Thread::getID() const
{ {
@ -135,8 +124,7 @@ Thread::operator!=(const Thread& thread) const
return !ARCH->isSameThread(m_thread, thread.m_thread); return !ARCH->isSameThread(m_thread, thread.m_thread);
} }
void* void Thread::threadFunc(const std::function<void()>& func)
Thread::threadFunc(void* vjob)
{ {
// get this thread's id for logging // get this thread's id for logging
IArchMultithread::ThreadID id; IArchMultithread::ThreadID id;
@ -146,42 +134,26 @@ Thread::threadFunc(void* vjob)
ARCH->closeThread(thread); ARCH->closeThread(thread);
} }
// get job
IJob* job = static_cast<IJob*>(vjob);
// run job
void* result = NULL;
try { try {
// go // go
LOG((CLOG_DEBUG1 "thread 0x%08x entry", id)); LOG((CLOG_DEBUG1 "thread 0x%08x entry", id));
job->run(); func();
LOG((CLOG_DEBUG1 "thread 0x%08x exit", id)); LOG((CLOG_DEBUG1 "thread 0x%08x exit", id));
} }
catch (XThreadCancel&) { catch (XThreadCancel&) {
// client called cancel() // client called cancel()
LOG((CLOG_DEBUG1 "caught cancel on thread 0x%08x", id)); LOG((CLOG_DEBUG1 "caught cancel on thread 0x%08x", id));
delete job;
throw; throw;
} }
catch (XThreadExit& e) { catch (XThreadExit&) {
// client called exit() LOG((CLOG_DEBUG1 "caught exit on thread 0x%08x", id));
result = e.m_result;
LOG((CLOG_DEBUG1 "caught exit on thread 0x%08x, result %p", id, result));
} }
catch (XBase& e) { catch (XBase& e) {
LOG((CLOG_ERR "exception on thread 0x%08x: %s", id, e.what())); LOG((CLOG_ERR "exception on thread 0x%08x: %s", id, e.what()));
delete job;
throw; throw;
} }
catch (...) { catch (...) {
LOG((CLOG_ERR "exception on thread 0x%08x: <unknown>", id)); LOG((CLOG_ERR "exception on thread 0x%08x: <unknown>", id));
delete job;
throw; throw;
} }
// done with job
delete job;
// return exit result
return result;
} }

View File

@ -19,8 +19,7 @@
#pragma once #pragma once
#include "arch/IArchMultithread.h" #include "arch/IArchMultithread.h"
#include <functional>
class IJob;
//! Thread handle //! Thread handle
/*! /*!
@ -44,10 +43,9 @@ class Thread {
public: public:
//! Run \c adoptedJob in a new thread //! Run \c adoptedJob in a new thread
/*! /*!
Create and start a new thread executing the \c adoptedJob. The Create and start a new thread executing the \c fun.
new thread takes ownership of \c adoptedJob and will delete it.
*/ */
Thread(IJob* adoptedJob); Thread(const std::function<void()>& fun);
//! Duplicate a thread handle //! Duplicate a thread handle
/*! /*!
@ -79,8 +77,7 @@ public:
/*! /*!
Terminate the calling thread. This function does not return but Terminate the calling thread. This function does not return but
the stack is unwound and automatic objects are destroyed, as if the stack is unwound and automatic objects are destroyed, as if
exit() threw an exception (which is, in fact, what it does). The exit() threw an exception (which is, in fact, what it does). If you
argument is saved as the result returned by getResult(). If you
have \c catch(...) blocks then you should add the following before have \c catch(...) blocks then you should add the following before
each to avoid catching the exit: each to avoid catching the exit:
\code \code
@ -167,16 +164,6 @@ public:
*/ */
bool wait(double timeout = -1.0) const; bool wait(double timeout = -1.0) const;
//! Get the exit result
/*!
Returns the exit result. This does an implicit wait(). It returns
NULL immediately if called by a thread on itself or on a thread that
was cancelled.
(cancellation point)
*/
void* getResult() const;
//! Get the thread id //! Get the thread id
/*! /*!
Returns an integer id for this thread. This id must not be used to Returns an integer id for this thread. This id must not be used to
@ -203,7 +190,7 @@ public:
private: private:
Thread(ArchThread); Thread(ArchThread);
static void* threadFunc(void*); static void threadFunc(const std::function<void()>& func);
private: private:
ArchThread m_thread; ArchThread m_thread;

View File

@ -26,12 +26,4 @@ Thrown by Thread::exit() to exit a thread. Clients of Thread
must not throw this type but must rethrow it if caught (by must not throw this type but must rethrow it if caught (by
XThreadExit, XThread, or ...). XThreadExit, XThread, or ...).
*/ */
class XThreadExit : public XThread { class XThreadExit : public XThread {};
public:
//! \c result is the result of the thread
XThreadExit(void* result) : m_result(result) { }
~XThreadExit() { }
public:
void* m_result;
};

View File

@ -20,7 +20,7 @@
#include "SecureSocket.h" #include "SecureSocket.h"
#include "net/NetworkAddress.h" #include "net/NetworkAddress.h"
#include "net/SocketMultiplexer.h" #include "net/SocketMultiplexer.h"
#include "net/TSocketMultiplexerMethodJob.h" #include "arch/Arch.h"
#include "arch/XArch.h" #include "arch/XArch.h"
#include "common/DataDirectories.h" #include "common/DataDirectories.h"
#include "base/String.h" #include "base/String.h"

View File

@ -140,16 +140,16 @@ std::unique_ptr<ISocketMultiplexerJob> SecureSocket::newJob()
void void
SecureSocket::secureConnect() SecureSocket::secureConnect()
{ {
setJob(std::make_unique<TSocketMultiplexerMethodJob<SecureSocket>>( setJob(std::make_unique<TSocketMultiplexerMethodJob>([this](auto j, auto r, auto w, auto e)
this, &SecureSocket::serviceConnect, { return serviceConnect(j, r, w, e); },
getSocket(), isReadable(), isWritable())); getSocket(), isReadable(), isWritable()));
} }
void void
SecureSocket::secureAccept() SecureSocket::secureAccept()
{ {
setJob(std::make_unique<TSocketMultiplexerMethodJob<SecureSocket>>( setJob(std::make_unique<TSocketMultiplexerMethodJob>([this](auto j, auto r, auto w, auto e)
this, &SecureSocket::serviceAccept, { return serviceAccept(j, r, w, e); },
getSocket(), isReadable(), isWritable())); getSocket(), isReadable(), isWritable()));
} }
@ -772,8 +772,8 @@ MultiplexerJobStatus SecureSocket::serviceConnect(ISocketMultiplexerJob* job,
// Retry case // Retry case
return { return {
true, true,
std::make_unique<TSocketMultiplexerMethodJob<SecureSocket>>( std::make_unique<TSocketMultiplexerMethodJob>([this](auto j, auto r, auto w, auto e)
this, &SecureSocket::serviceConnect, { return serviceConnect(j, r, w, e); },
getSocket(), isReadable(), isWritable()) getSocket(), isReadable(), isWritable())
}; };
} }
@ -802,9 +802,12 @@ MultiplexerJobStatus SecureSocket::serviceAccept(ISocketMultiplexerJob* job,
} }
// Retry case // Retry case
return {true, std::make_unique<TSocketMultiplexerMethodJob<SecureSocket>>( return {
this, &SecureSocket::serviceAccept, true,
getSocket(), isReadable(), isWritable())}; std::make_unique<TSocketMultiplexerMethodJob>([this](auto j, auto r, auto w, auto e)
{ return serviceAccept(j, r, w, e); },
getSocket(), isReadable(), isWritable())
};
} }
void void

View File

@ -26,7 +26,6 @@
#include "arch/Arch.h" #include "arch/Arch.h"
#include "arch/XArch.h" #include "arch/XArch.h"
#include "base/Log.h" #include "base/Log.h"
#include "base/TMethodJob.h"
#include "common/stdvector.h" #include "common/stdvector.h"
// //
@ -58,8 +57,7 @@ SocketMultiplexer::SocketMultiplexer() :
m_jobListLockLocker(NULL) m_jobListLockLocker(NULL)
{ {
// start thread // start thread
m_thread = new Thread(new TMethodJob<SocketMultiplexer>( m_thread = new Thread([this](){ service_thread(); });
this, &SocketMultiplexer::serviceThread));
} }
SocketMultiplexer::~SocketMultiplexer() SocketMultiplexer::~SocketMultiplexer()
@ -95,7 +93,7 @@ void SocketMultiplexer::addSocket(ISocket* socket, std::unique_ptr<ISocketMultip
if (i == m_socketJobMap.end()) { if (i == m_socketJobMap.end()) {
// we *must* put the job at the end so the order of jobs in // we *must* put the job at the end so the order of jobs in
// the list continue to match the order of jobs in pfds in // the list continue to match the order of jobs in pfds in
// serviceThread(). // service_thread().
JobCursor j = m_socketJobs.insert(m_socketJobs.end(), std::move(job)); JobCursor j = m_socketJobs.insert(m_socketJobs.end(), std::move(job));
m_update = true; m_update = true;
m_socketJobMap.insert(std::make_pair(socket, j)); m_socketJobMap.insert(std::make_pair(socket, j));
@ -125,7 +123,7 @@ SocketMultiplexer::removeSocket(ISocket* socket)
// remove job. rather than removing it from the map we put NULL // remove job. rather than removing it from the map we put NULL
// in the list instead so the order of jobs in the list continues // in the list instead so the order of jobs in the list continues
// to match the order of jobs in pfds in serviceThread(). // to match the order of jobs in pfds in service_thread().
SocketJobMap::iterator i = m_socketJobMap.find(socket); SocketJobMap::iterator i = m_socketJobMap.find(socket);
if (i != m_socketJobMap.end()) { if (i != m_socketJobMap.end()) {
if (*(i->second)) { if (*(i->second)) {
@ -138,8 +136,7 @@ SocketMultiplexer::removeSocket(ISocket* socket)
unlockJobList(); unlockJobList();
} }
void void SocketMultiplexer::service_thread()
SocketMultiplexer::serviceThread(void*)
{ {
std::vector<IArchNetwork::PollEntry> pfds; std::vector<IArchNetwork::PollEntry> pfds;
IArchNetwork::PollEntry pfd; IArchNetwork::PollEntry pfd;

View File

@ -67,7 +67,7 @@ private:
// and m_update while m_pollable and m_polling are true. all other // 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 // threads must only modify these when m_pollable and m_polling are
// false. only the service thread sets m_polling. // false. only the service thread sets m_polling.
void serviceThread(void*); void service_thread();
// create, iterate, and destroy a cursor. a cursor is used to // create, iterate, and destroy a cursor. a cursor is used to
// safely iterate through the job list while other threads modify // safely iterate through the job list while other threads modify

View File

@ -70,8 +70,10 @@ TCPListenSocket::bind(const NetworkAddress& addr)
ARCH->bindSocket(m_socket, addr.getAddress()); ARCH->bindSocket(m_socket, addr.getAddress());
ARCH->listenOnSocket(m_socket); ARCH->listenOnSocket(m_socket);
auto new_job = std::make_unique<TSocketMultiplexerMethodJob<TCPListenSocket>>( auto new_job = std::make_unique<TSocketMultiplexerMethodJob>(
this, &TCPListenSocket::serviceListening, m_socket, true, false); [this](auto j, auto r, auto w, auto e)
{ return serviceListening(j, r, w, e); },
m_socket, true, false);
m_socketMultiplexer->addSocket(this, std::move(new_job)); m_socketMultiplexer->addSocket(this, std::move(new_job));
} }
@ -136,8 +138,10 @@ TCPListenSocket::accept()
void void
TCPListenSocket::setListeningJob() TCPListenSocket::setListeningJob()
{ {
auto new_job = std::make_unique<TSocketMultiplexerMethodJob<TCPListenSocket>>( auto new_job = std::make_unique<TSocketMultiplexerMethodJob>(
this, &TCPListenSocket::serviceListening, m_socket, true, false); [this](auto j, auto r, auto w, auto e)
{ return serviceListening(j, r, w, e); },
m_socket, true, false);
m_socketMultiplexer->addSocket(this, std::move(new_job)); m_socketMultiplexer->addSocket(this, std::move(new_job));
} }

View File

@ -426,18 +426,20 @@ std::unique_ptr<ISocketMultiplexerJob> TCPSocket::newJob()
if (!(m_readable || m_writable)) { if (!(m_readable || m_writable)) {
return {}; return {};
} }
return std::make_unique<TSocketMultiplexerMethodJob<TCPSocket>>( return std::make_unique<TSocketMultiplexerMethodJob>(
this, &TCPSocket::serviceConnecting, [this](auto j, auto r, auto w, auto e)
{ return serviceConnecting(j, r, w, e); },
m_socket, m_readable, m_writable); m_socket, m_readable, m_writable);
} }
else { else {
if (!(m_readable || (m_writable && (m_outputBuffer.getSize() > 0)))) { auto writable = m_writable && (m_outputBuffer.getSize() > 0);
if (!(m_readable || writable)) {
return {}; return {};
} }
return std::make_unique<TSocketMultiplexerMethodJob<TCPSocket>>( return std::make_unique<TSocketMultiplexerMethodJob>(
this, &TCPSocket::serviceConnected, [this](auto j, auto r, auto w, auto e)
m_socket, m_readable, { return serviceConnected(j, r, w, e); },
m_writable && (m_outputBuffer.getSize() > 0)); m_socket, m_readable, writable);
} }
} }

View File

@ -25,81 +25,43 @@
/*! /*!
A socket multiplexer job class that invokes a member function. A socket multiplexer job class that invokes a member function.
*/ */
template <class T>
class TSocketMultiplexerMethodJob : public ISocketMultiplexerJob { class TSocketMultiplexerMethodJob : public ISocketMultiplexerJob {
public: public:
using Method = MultiplexerJobStatus (T::*)(ISocketMultiplexerJob*, bool, bool, bool); using RunFunction = std::function<MultiplexerJobStatus(ISocketMultiplexerJob*, bool, bool, bool)>;
//! run() invokes \c object->method(arg) //! run() invokes \c object->method(arg)
TSocketMultiplexerMethodJob(T* object, Method method, TSocketMultiplexerMethodJob(const RunFunction& func,
ArchSocket socket, bool readable, bool writeable); ArchSocket socket, bool readable, bool writable) :
virtual ~TSocketMultiplexerMethodJob(); func_{func},
// IJob overrides
virtual MultiplexerJobStatus run(bool readable, bool writable, bool error) override;
virtual ArchSocket getSocket() const override;
virtual bool isReadable() const override;
virtual bool isWritable() const override;
private:
T* m_object;
Method m_method;
ArchSocket m_socket;
bool m_readable;
bool m_writable;
void* m_arg;
};
template <class T>
inline
TSocketMultiplexerMethodJob<T>::TSocketMultiplexerMethodJob(T* object,
Method method, ArchSocket socket,
bool readable, bool writable) :
m_object(object),
m_method(method),
m_socket(ARCH->copySocket(socket)), m_socket(ARCH->copySocket(socket)),
m_readable(readable), m_readable(readable),
m_writable(writable) m_writable(writable)
{ {
// do nothing }
}
template <class T> ~TSocketMultiplexerMethodJob() override
inline {
TSocketMultiplexerMethodJob<T>::~TSocketMultiplexerMethodJob()
{
ARCH->closeSocket(m_socket); ARCH->closeSocket(m_socket);
} }
template <class T> // IJob overrides
inline MultiplexerJobStatus TSocketMultiplexerMethodJob<T>::run(bool read, bool write, bool error) virtual MultiplexerJobStatus run(bool readable, bool writable, bool error) override
{ {
if (m_object != NULL) { if (func_) {
return (m_object->*m_method)(this, read, write, error); return func_(this, readable, writable, error);
} }
return {false, {}}; return {false, {}};
} }
template <class T> virtual ArchSocket getSocket() const override { return m_socket; }
inline virtual bool isReadable() const override { return m_readable; }
ArchSocket virtual bool isWritable() const override { return m_writable; }
TSocketMultiplexerMethodJob<T>::getSocket() const
{ private:
return m_socket; RunFunction func_;
} ArchSocket m_socket;
bool m_readable;
bool m_writable;
};
template <class T>
inline
bool
TSocketMultiplexerMethodJob<T>::isReadable() const
{
return m_readable;
}
template <class T>
inline
bool
TSocketMultiplexerMethodJob<T>::isWritable() const
{
return m_writable;
}

View File

@ -27,9 +27,7 @@
#include "arch/win32/ArchMiscWindows.h" #include "arch/win32/ArchMiscWindows.h"
#include "base/Log.h" #include "base/Log.h"
#include "base/IEventQueue.h" #include "base/IEventQueue.h"
#include "base/IJob.h"
#include "base/TMethodEventJob.h" #include "base/TMethodEventJob.h"
#include "base/TMethodJob.h"
#include "base/IEventQueue.h" #include "base/IEventQueue.h"
#include <malloc.h> #include <malloc.h>
@ -97,10 +95,9 @@
// MSWindowsDesks // MSWindowsDesks
// //
MSWindowsDesks::MSWindowsDesks( MSWindowsDesks::MSWindowsDesks(bool isPrimary, bool noHooks,
bool isPrimary, bool noHooks,
const IScreenSaver* screensaver, IEventQueue* events, const IScreenSaver* screensaver, IEventQueue* events,
IJob* updateKeys, bool stopOnDeskSwitch) : const std::function<void()>& updateKeys, bool stopOnDeskSwitch) :
m_isPrimary(isPrimary), m_isPrimary(isPrimary),
m_noHooks(noHooks), m_noHooks(noHooks),
m_isOnScreen(m_isPrimary), m_isOnScreen(m_isPrimary),
@ -130,7 +127,6 @@ MSWindowsDesks::~MSWindowsDesks()
disable(); disable();
destroyClass(m_deskClass); destroyClass(m_deskClass);
destroyCursor(m_cursor); destroyCursor(m_cursor);
delete m_updateKeys;
} }
void void
@ -602,13 +598,11 @@ MSWindowsDesks::deskLeave(Desk* desk, HKL keyLayout)
} }
} }
void void MSWindowsDesks::desk_thread(Desk* desk)
MSWindowsDesks::deskThread(void* vdesk)
{ {
MSG msg; MSG msg;
// use given desktop for this thread // use given desktop for this thread
Desk* desk = static_cast<Desk*>(vdesk);
desk->m_threadID = GetCurrentThreadId(); desk->m_threadID = GetCurrentThreadId();
desk->m_window = NULL; desk->m_window = NULL;
desk->m_foregroundWindow = NULL; desk->m_foregroundWindow = NULL;
@ -709,7 +703,7 @@ MSWindowsDesks::deskThread(void* vdesk)
} }
case BARRIER_MSG_SYNC_KEYS: case BARRIER_MSG_SYNC_KEYS:
m_updateKeys->run(); m_updateKeys();
break; break;
case BARRIER_MSG_SCREENSAVER: case BARRIER_MSG_SCREENSAVER:
@ -752,8 +746,7 @@ MSWindowsDesks::Desk* MSWindowsDesks::addDesk(const std::string& name, HDESK hde
desk->m_name = name; desk->m_name = name;
desk->m_desk = hdesk; desk->m_desk = hdesk;
desk->m_targetID = GetCurrentThreadId(); desk->m_targetID = GetCurrentThreadId();
desk->m_thread = new Thread(new TMethodJob<MSWindowsDesks>( desk->m_thread = new Thread([this, desk]() { desk_thread(desk); });
this, &MSWindowsDesks::deskThread, desk));
waitForDesk(); waitForDesk();
m_desks.insert(std::make_pair(name, desk)); m_desks.insert(std::make_pair(name, desk));
return desk; return desk;

View File

@ -26,15 +26,16 @@
#include "mt/CondVar.h" #include "mt/CondVar.h"
#include "mt/Mutex.h" #include "mt/Mutex.h"
#include "common/stdmap.h" #include "common/stdmap.h"
#include <functional>
#include <string> #include <string>
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
class Event; class Event;
class EventQueueTimer; class EventQueueTimer;
class Thread; class Thread;
class IJob;
class IScreenSaver; class IScreenSaver;
class IEventQueue; class IEventQueue;
@ -68,7 +69,7 @@ public:
MSWindowsDesks( MSWindowsDesks(
bool isPrimary, bool noHooks, bool isPrimary, bool noHooks,
const IScreenSaver* screensaver, IEventQueue* events, const IScreenSaver* screensaver, IEventQueue* events,
IJob* updateKeys, bool stopOnDeskSwitch); const std::function<void()>& updateKeys, bool stopOnDeskSwitch);
~MSWindowsDesks(); ~MSWindowsDesks();
//! @name manipulators //! @name manipulators
@ -219,7 +220,7 @@ private:
void deskMouseRelativeMove(SInt32 dx, SInt32 dy) const; void deskMouseRelativeMove(SInt32 dx, SInt32 dy) const;
void deskEnter(Desk* desk); void deskEnter(Desk* desk);
void deskLeave(Desk* desk, HKL keyLayout); void deskLeave(Desk* desk, HKL keyLayout);
void deskThread(void* vdesk); void desk_thread(Desk* desk);
// desk switch checking and handling // desk switch checking and handling
Desk* addDesk(const std::string& name, HDESK hdesk); Desk* addDesk(const std::string& name, HDESK hdesk);
@ -284,7 +285,7 @@ private:
Desks m_desks; Desks m_desks;
// keyboard stuff // keyboard stuff
IJob* m_updateKeys; std::function<void()> m_updateKeys;
HKL m_keyLayout; HKL m_keyLayout;
// options // options

View File

@ -21,7 +21,6 @@
#include "platform/MSWindowsDesks.h" #include "platform/MSWindowsDesks.h"
#include "mt/Thread.h" #include "mt/Thread.h"
#include "arch/win32/ArchMiscWindows.h" #include "arch/win32/ArchMiscWindows.h"
#include "base/FunctionJob.h"
#include "base/Log.h" #include "base/Log.h"
#include "base/String.h" #include "base/String.h"
#include "base/IEventQueue.h" #include "base/IEventQueue.h"
@ -804,15 +803,14 @@ MSWindowsKeyState::fakeCtrlAltDel()
CloseHandle(hEvtSendSas); CloseHandle(hEvtSendSas);
} }
else { else {
Thread cad(new FunctionJob(&MSWindowsKeyState::ctrlAltDelThread)); Thread cad([this](){ ctrl_alt_del_thread(); });
cad.wait(); cad.wait();
} }
return true; return true;
} }
void void MSWindowsKeyState::ctrl_alt_del_thread()
MSWindowsKeyState::ctrlAltDelThread(void*)
{ {
// get the Winlogon desktop at whatever privilege we can // get the Winlogon desktop at whatever privilege we can
HDESK desk = OpenDesktop("Winlogon", 0, FALSE, MAXIMUM_ALLOWED); HDESK desk = OpenDesktop("Winlogon", 0, FALSE, MAXIMUM_ALLOWED);

View File

@ -169,7 +169,7 @@ private:
typedef std::vector<HKL> GroupList; typedef std::vector<HKL> GroupList;
// send ctrl+alt+del hotkey event on NT family // send ctrl+alt+del hotkey event on NT family
static void ctrlAltDelThread(void*); static void ctrl_alt_del_thread();
bool getGroups(GroupList&) const; bool getGroups(GroupList&) const;
void setWindowGroup(SInt32 group); void setWindowGroup(SInt32 group);

View File

@ -36,11 +36,9 @@
#include "mt/Thread.h" #include "mt/Thread.h"
#include "arch/win32/ArchMiscWindows.h" #include "arch/win32/ArchMiscWindows.h"
#include "arch/Arch.h" #include "arch/Arch.h"
#include "base/FunctionJob.h"
#include "base/Log.h" #include "base/Log.h"
#include "base/IEventQueue.h" #include "base/IEventQueue.h"
#include "base/TMethodEventJob.h" #include "base/TMethodEventJob.h"
#include "base/TMethodJob.h"
#include <string.h> #include <string.h>
#include <Shlobj.h> #include <Shlobj.h>
@ -134,8 +132,7 @@ MSWindowsScreen::MSWindowsScreen(
m_noHooks, m_noHooks,
m_screensaver, m_screensaver,
m_events, m_events,
new TMethodJob<MSWindowsScreen>( [this]() { updateKeysCB(); },
this, &MSWindowsScreen::updateKeysCB),
stopOnDeskSwitch); stopOnDeskSwitch);
m_keyState = new MSWindowsKeyState(m_desks, getEventTarget(), m_events); m_keyState = new MSWindowsKeyState(m_desks, getEventTarget(), m_events);
@ -355,17 +352,13 @@ MSWindowsScreen::leave()
forceShowCursor(); forceShowCursor();
if (isDraggingStarted() && !m_isPrimary) { if (isDraggingStarted() && !m_isPrimary) {
m_sendDragThread = new Thread( m_sendDragThread = new Thread([this](){ send_drag_thread(); });
new TMethodJob<MSWindowsScreen>(
this,
&MSWindowsScreen::sendDragThread));
} }
return true; return true;
} }
void void MSWindowsScreen::send_drag_thread()
MSWindowsScreen::sendDragThread(void*)
{ {
std::string& draggingFilename = getDraggingFilename(); std::string& draggingFilename = getDraggingFilename();
size_t size = draggingFilename.size(); size_t size = draggingFilename.size();
@ -1713,7 +1706,7 @@ MSWindowsScreen::mapPressFromEvent(WPARAM msg, LPARAM) const
} }
void void
MSWindowsScreen::updateKeysCB(void*) MSWindowsScreen::updateKeysCB()
{ {
// record which keys we think are down // record which keys we think are down
bool down[IKeyState::kNumButtons]; bool down[IKeyState::kNumButtons];

View File

@ -199,7 +199,7 @@ private: // HACK
bool mapPressFromEvent(WPARAM msg, LPARAM button) const; bool mapPressFromEvent(WPARAM msg, LPARAM button) const;
// job to update the key state // job to update the key state
void updateKeysCB(void*); void updateKeysCB();
// determine whether the mouse is hidden by the system and force // determine whether the mouse is hidden by the system and force
// it to be displayed if user has entered this secondary screen. // it to be displayed if user has entered this secondary screen.
@ -222,7 +222,7 @@ private: // HACK
KeyModifierMask state, WPARAM wParam) const; KeyModifierMask state, WPARAM wParam) const;
// send drag info and data back to server // send drag info and data back to server
void sendDragThread(void*); void send_drag_thread();
private: private:
struct HotKeyItem { struct HotKeyItem {

View File

@ -23,7 +23,6 @@
#include "arch/Arch.h" #include "arch/Arch.h"
#include "arch/win32/ArchMiscWindows.h" #include "arch/win32/ArchMiscWindows.h"
#include "base/Log.h" #include "base/Log.h"
#include "base/TMethodJob.h"
#include <malloc.h> #include <malloc.h>
#include <tchar.h> #include <tchar.h>
@ -223,8 +222,7 @@ MSWindowsScreenSaver::watchDesktop()
// watch desktop in another thread // watch desktop in another thread
LOG((CLOG_DEBUG "watching screen saver desktop")); LOG((CLOG_DEBUG "watching screen saver desktop"));
m_active = true; m_active = true;
m_watch = new Thread(new TMethodJob<MSWindowsScreenSaver>(this, m_watch = new Thread([this](){ watch_desktop_thread(); });
&MSWindowsScreenSaver::watchDesktopThread));
} }
void void
@ -238,8 +236,7 @@ MSWindowsScreenSaver::watchProcess(HANDLE process)
LOG((CLOG_DEBUG "watching screen saver process")); LOG((CLOG_DEBUG "watching screen saver process"));
m_process = process; m_process = process;
m_active = true; m_active = true;
m_watch = new Thread(new TMethodJob<MSWindowsScreenSaver>(this, m_watch = new Thread([this](){ watch_process_thread(); });
&MSWindowsScreenSaver::watchProcessThread));
} }
} }
@ -260,8 +257,7 @@ MSWindowsScreenSaver::unwatchProcess()
} }
} }
void void MSWindowsScreenSaver::watch_desktop_thread()
MSWindowsScreenSaver::watchDesktopThread(void*)
{ {
DWORD reserved = 0; DWORD reserved = 0;
TCHAR* name = NULL; TCHAR* name = NULL;
@ -283,8 +279,7 @@ MSWindowsScreenSaver::watchDesktopThread(void*)
} }
} }
void void MSWindowsScreenSaver::watch_process_thread()
MSWindowsScreenSaver::watchProcessThread(void*)
{ {
for (;;) { for (;;) {
Thread::testCancel(); Thread::testCancel();

View File

@ -64,8 +64,8 @@ private:
void watchDesktop(); void watchDesktop();
void watchProcess(HANDLE process); void watchProcess(HANDLE process);
void unwatchProcess(); void unwatchProcess();
void watchDesktopThread(void*); void watch_desktop_thread();
void watchProcessThread(void*); void watch_process_thread();
void setSecure(bool secure, bool saveSecureAsInt); void setSecure(bool secure, bool saveSecureAsInt);
bool isSecure(bool* wasSecureAnInt) const; bool isSecure(bool* wasSecureAnInt) const;

View File

@ -29,7 +29,6 @@
#include "arch/win32/XArchWindows.h" #include "arch/win32/XArchWindows.h"
#include "arch/Arch.h" #include "arch/Arch.h"
#include "base/log_outputters.h" #include "base/log_outputters.h"
#include "base/TMethodJob.h"
#include "base/Log.h" #include "base/Log.h"
#include "common/Version.h" #include "common/Version.h"
@ -84,11 +83,8 @@ MSWindowsWatchdog::MSWindowsWatchdog(
void void
MSWindowsWatchdog::startAsync() MSWindowsWatchdog::startAsync()
{ {
m_thread = new Thread(new TMethodJob<MSWindowsWatchdog>( m_thread = new Thread([this](){ main_loop(); });
this, &MSWindowsWatchdog::mainLoop, nullptr)); m_outputThread = new Thread([this](){ output_loop(); });
m_outputThread = new Thread(new TMethodJob<MSWindowsWatchdog>(
this, &MSWindowsWatchdog::outputLoop, nullptr));
} }
void void
@ -157,8 +153,7 @@ MSWindowsWatchdog::getUserToken(LPSECURITY_ATTRIBUTES security)
} }
} }
void void MSWindowsWatchdog::main_loop()
MSWindowsWatchdog::mainLoop(void*)
{ {
shutdownExistingProcesses(); shutdownExistingProcesses();
@ -421,8 +416,7 @@ MSWindowsWatchdog::getCommand() const
return cmd; return cmd;
} }
void void MSWindowsWatchdog::output_loop()
MSWindowsWatchdog::outputLoop(void*)
{ {
// +1 char for \0 // +1 char for \0
CHAR buffer[kOutputBufferSize + 1]; CHAR buffer[kOutputBufferSize + 1];

View File

@ -48,8 +48,8 @@ public:
void setFileLogOutputter(FileLogOutputter* outputter); void setFileLogOutputter(FileLogOutputter* outputter);
private: private:
void mainLoop(void*); void main_loop();
void outputLoop(void*); void output_loop();
void shutdownProcess(HANDLE handle, DWORD pid, int timeout); void shutdownProcess(HANDLE handle, DWORD pid, int timeout);
void shutdownExistingProcesses(); void shutdownExistingProcesses();
HANDLE duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security); HANDLE duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security);

View File

@ -174,7 +174,7 @@ private:
EventRef theEvent, void* inUserData); EventRef theEvent, void* inUserData);
// sleep / wakeup support // sleep / wakeup support
void watchSystemPowerThread(void*); void watchSystemPowerThread();
static void testCanceled(CFRunLoopTimerRef timer, void*info); static void testCanceled(CFRunLoopTimerRef timer, void*info);
static void powerChangeCallback(void* refcon, io_service_t service, static void powerChangeCallback(void* refcon, io_service_t service,
natural_t messageType, void* messageArgument); natural_t messageType, void* messageArgument);
@ -201,7 +201,7 @@ private:
// convert CFString to char* // convert CFString to char*
static char* CFStringRefToUTF8String(CFStringRef aString); static char* CFStringRefToUTF8String(CFStringRef aString);
void getDropTargetThread(void*); void get_drop_target_thread();
private: private:
struct HotKeyItem { struct HotKeyItem {

View File

@ -38,7 +38,6 @@
#include "base/Log.h" #include "base/Log.h"
#include "base/IEventQueue.h" #include "base/IEventQueue.h"
#include "base/TMethodEventJob.h" #include "base/TMethodEventJob.h"
#include "base/TMethodJob.h"
#include <math.h> #include <math.h>
#include <mach-o/dyld.h> #include <mach-o/dyld.h>
@ -157,8 +156,7 @@ OSXScreen::OSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCurso
m_carbonLoopReady = new CondVar<bool>(m_carbonLoopMutex, false); m_carbonLoopReady = new CondVar<bool>(m_carbonLoopMutex, false);
#endif #endif
LOG((CLOG_DEBUG "starting watchSystemPowerThread")); LOG((CLOG_DEBUG "starting watchSystemPowerThread"));
m_pmWatchThread = new Thread(new TMethodJob<OSXScreen> m_pmWatchThread = new Thread([this](){ watchSystemPowerThread(); });
(this, &OSXScreen::watchSystemPowerThread));
} }
catch (...) { catch (...) {
m_events->removeHandler(m_events->forOSXScreen().confirmSleep(), m_events->removeHandler(m_events->forOSXScreen().confirmSleep(),
@ -578,16 +576,14 @@ OSXScreen::fakeMouseButton(ButtonID id, bool press)
if (!press && (id == kButtonLeft)) { if (!press && (id == kButtonLeft)) {
if (m_fakeDraggingStarted) { if (m_fakeDraggingStarted) {
m_getDropTargetThread = new Thread(new TMethodJob<OSXScreen>( m_getDropTargetThread = new Thread([this](){ get_drop_target_thread(); });
this, &OSXScreen::getDropTargetThread));
} }
m_draggingStarted = false; m_draggingStarted = false;
} }
} }
void void OSXScreen::get_drop_target_thread()
OSXScreen::getDropTargetThread(void*)
{ {
#if defined(MAC_OS_X_VERSION_10_7) #if defined(MAC_OS_X_VERSION_10_7)
char* cstr = NULL; char* cstr = NULL;
@ -1186,8 +1182,7 @@ OSXScreen::onMouseButton(bool pressed, UInt16 macButton)
} }
else { else {
if (m_fakeDraggingStarted) { if (m_fakeDraggingStarted) {
m_getDropTargetThread = new Thread(new TMethodJob<OSXScreen>( m_getDropTargetThread = new Thread([this](){ get_drop_target_thread(); });
this, &OSXScreen::getDropTargetThread));
} }
m_draggingStarted = false; m_draggingStarted = false;
@ -1621,8 +1616,7 @@ OSXScreen::userSwitchCallback(EventHandlerCallRef nextHandler,
// main of thread monitoring system power (sleep/wakeup) using a CFRunLoop // main of thread monitoring system power (sleep/wakeup) using a CFRunLoop
// //
void void OSXScreen::watchSystemPowerThread()
OSXScreen::watchSystemPowerThread(void*)
{ {
io_object_t notifier; io_object_t notifier;
IONotificationPortRef notificationPortRef; IONotificationPortRef notificationPortRef;

View File

@ -39,7 +39,6 @@
#include "net/XSocket.h" #include "net/XSocket.h"
#include "mt/Thread.h" #include "mt/Thread.h"
#include "arch/Arch.h" #include "arch/Arch.h"
#include "base/TMethodJob.h"
#include "base/IEventQueue.h" #include "base/IEventQueue.h"
#include "base/Log.h" #include "base/Log.h"
#include "base/TMethodEventJob.h" #include "base/TMethodEventJob.h"
@ -1824,10 +1823,8 @@ Server::onMouseMovePrimary(SInt32 x, SInt32 y)
&& m_active != newScreen && m_active != newScreen
&& m_waitDragInfoThread) { && m_waitDragInfoThread) {
if (m_sendDragInfoThread == NULL) { if (m_sendDragInfoThread == NULL) {
m_sendDragInfoThread = new Thread( m_sendDragInfoThread = new Thread([this, newScreen]()
new TMethodJob<Server>( { send_drag_info_thread(newScreen); });
this,
&Server::sendDragInfoThread, newScreen));
} }
return false; return false;
@ -1843,11 +1840,8 @@ Server::onMouseMovePrimary(SInt32 x, SInt32 y)
return false; return false;
} }
void void Server::send_drag_info_thread(BaseClientProxy* newScreen)
Server::sendDragInfoThread(void* arg)
{ {
BaseClientProxy* newScreen = static_cast<BaseClientProxy*>(arg);
m_dragFileList.clear(); m_dragFileList.clear();
std::string& dragFileList = m_screen->getDraggingFilename(); std::string& dragFileList = m_screen->getDraggingFilename();
if (!dragFileList.empty()) { if (!dragFileList.empty()) {
@ -2087,14 +2081,11 @@ void
Server::onFileRecieveCompleted() Server::onFileRecieveCompleted()
{ {
if (isReceivedFileSizeValid()) { if (isReceivedFileSizeValid()) {
m_writeToDropDirThread = new Thread( m_writeToDropDirThread = new Thread([this]() { write_to_drop_dir_thread(); });
new TMethodJob<Server>(
this, &Server::writeToDropDirThread));
} }
} }
void void Server::write_to_drop_dir_thread()
Server::writeToDropDirThread(void*)
{ {
LOG((CLOG_DEBUG "starting write to drop dir thread")); LOG((CLOG_DEBUG "starting write to drop dir thread"));
@ -2394,17 +2385,12 @@ Server::sendFileToClient(const char* filename)
StreamChunker::interruptFile(); StreamChunker::interruptFile();
} }
m_sendFileThread = new Thread( m_sendFileThread = new Thread([this, filename]() { send_file_thread(filename); });
new TMethodJob<Server>(
this, &Server::sendFileThread,
static_cast<void*>(const_cast<char*>(filename))));
} }
void void Server::send_file_thread(const char* filename)
Server::sendFileThread(void* data)
{ {
try { try {
char* filename = static_cast<char*>(data);
LOG((CLOG_DEBUG "sending file to client, filename=%s", filename)); LOG((CLOG_DEBUG "sending file to client, filename=%s", filename));
StreamChunker::sendFile(filename, m_events, this); StreamChunker::sendFile(filename, m_events, this);
} }

View File

@ -358,13 +358,13 @@ private:
void forceLeaveClient(BaseClientProxy* client); void forceLeaveClient(BaseClientProxy* client);
// thread function for sending file // thread function for sending file
void sendFileThread(void*); void send_file_thread(const char* filename);
// thread function for writing file to drop directory // thread function for writing file to drop directory
void writeToDropDirThread(void*); void write_to_drop_dir_thread();
// thread function for sending drag information // thread function for sending drag information
void sendDragInfoThread(void*); void send_drag_info_thread(BaseClientProxy* newScreen);
// send drag info to new client screen // send drag info to new client screen
void sendDragInfo(BaseClientProxy* newScreen); void sendDragInfo(BaseClientProxy* newScreen);

View File

@ -31,7 +31,6 @@
#include "net/SocketMultiplexer.h" #include "net/SocketMultiplexer.h"
#include "mt/Thread.h" #include "mt/Thread.h"
#include "arch/Arch.h" #include "arch/Arch.h"
#include "base/TMethodJob.h"
#include "base/String.h" #include "base/String.h"
#include "base/Log.h" #include "base/Log.h"
#include "base/EventQueue.h" #include "base/EventQueue.h"

View File

@ -36,7 +36,6 @@
#include "net/TCPSocketFactory.h" #include "net/TCPSocketFactory.h"
#include "mt/Thread.h" #include "mt/Thread.h"
#include "base/TMethodEventJob.h" #include "base/TMethodEventJob.h"
#include "base/TMethodJob.h"
#include "base/Log.h" #include "base/Log.h"
#include <stdexcept> #include <stdexcept>

View File

@ -24,7 +24,6 @@
#include "platform/MSWindowsDesks.h" #include "platform/MSWindowsDesks.h"
#include "platform/MSWindowsScreen.h" #include "platform/MSWindowsScreen.h"
#include "platform/MSWindowsScreenSaver.h" #include "platform/MSWindowsScreenSaver.h"
#include "base/TMethodJob.h"
#include "test/global/gtest.h" #include "test/global/gtest.h"
#include "test/global/gmock.h" #include "test/global/gmock.h"
@ -50,10 +49,7 @@ protected:
MSWindowsDesks* newDesks(IEventQueue* eventQueue) MSWindowsDesks* newDesks(IEventQueue* eventQueue)
{ {
return new MSWindowsDesks( return new MSWindowsDesks(true, false, m_screensaver, eventQueue, [](){}, false);
true, false, m_screensaver, eventQueue,
new TMethodJob<MSWindowsKeyStateTests>(
this, &MSWindowsKeyStateTests::updateKeysCB), false);
} }
void* getEventTarget() const void* getEventTarget() const
@ -62,9 +58,7 @@ protected:
} }
private: private:
void updateKeysCB(void*) { }
IScreenSaver* m_screensaver; IScreenSaver* m_screensaver;
MSWindowsHook m_hook;
}; };
TEST_F(MSWindowsKeyStateTests, disable_eventQueueNotUsed) TEST_F(MSWindowsKeyStateTests, disable_eventQueueNotUsed)