fixed timeout bug in CThreadRep::wait() (negative timeout wouldn't
wait forever). also fixed early return from sleep due to signal. now forcing client to initialize CThread to ensure global mutex gets initialized before threads are used.
This commit is contained in:
parent
6aba3a6f57
commit
b3291bc2b5
|
@ -16,12 +16,15 @@ class CLog {
|
||||||
|
|
||||||
#if defined(NOLOGGING)
|
#if defined(NOLOGGING)
|
||||||
#define log(_a1)
|
#define log(_a1)
|
||||||
|
#define logc(_a1, _a2)
|
||||||
#define CLOG_TRACE
|
#define CLOG_TRACE
|
||||||
#elif defined(NDEBUG)
|
#elif defined(NDEBUG)
|
||||||
#define log(_a1) CLog::print _a1
|
#define log(_a1) CLog::print _a1
|
||||||
|
#define logc(_a1, _a2) if (_a1) CLog::print _a2
|
||||||
#define CLOG_TRACE
|
#define CLOG_TRACE
|
||||||
#else
|
#else
|
||||||
#define log(_a1) CLog::printt _a1
|
#define log(_a1) CLog::printt _a1
|
||||||
|
#define logc(_a1, _a2) if (_a1) CLog::printt _a2
|
||||||
#define CLOG_TRACE __FILE__, __LINE__,
|
#define CLOG_TRACE __FILE__, __LINE__,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "CMutex.h"
|
#include "CMutex.h"
|
||||||
|
#include "CLog.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -40,10 +41,15 @@ void CMutex::init()
|
||||||
m_mutex = reinterpret_cast<void*>(mutex);
|
m_mutex = reinterpret_cast<void*>(mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
void CMutex::fini()
|
void CMutex::fini()
|
||||||
{
|
{
|
||||||
pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(m_mutex);
|
pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(m_mutex);
|
||||||
int status = pthread_mutex_destroy(mutex);
|
int status = pthread_mutex_destroy(mutex);
|
||||||
|
logc(status != 0, (CLOG_ERR "pthread_mutex_destroy status %d", status));
|
||||||
assert(status == 0);
|
assert(status == 0);
|
||||||
delete mutex;
|
delete mutex;
|
||||||
}
|
}
|
||||||
|
@ -67,6 +73,7 @@ void CMutex::lock() const
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
log((CLOG_ERR "pthread_mutex_lock status %d", status));
|
||||||
assert(0 && "unexpected error");
|
assert(0 && "unexpected error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,6 +93,7 @@ void CMutex::unlock() const
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
log((CLOG_ERR "pthread_mutex_unlock status %d", status));
|
||||||
assert(0 && "unexpected error");
|
assert(0 && "unexpected error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,11 @@ CThread& CThread::operator=(const CThread& thread)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CThread::init()
|
||||||
|
{
|
||||||
|
CThreadRep::initThreads();
|
||||||
|
}
|
||||||
|
|
||||||
void CThread::sleep(double timeout)
|
void CThread::sleep(double timeout)
|
||||||
{
|
{
|
||||||
CThreadPtr currentRep(CThreadRep::getCurrentThreadRep());
|
CThreadPtr currentRep(CThreadRep::getCurrentThreadRep());
|
||||||
|
|
|
@ -28,6 +28,11 @@ class CThread {
|
||||||
// start a new thread.
|
// start a new thread.
|
||||||
CThread& operator=(const CThread&);
|
CThread& operator=(const CThread&);
|
||||||
|
|
||||||
|
// initialize the thread library. this must be called before
|
||||||
|
// any other thread methods or creating a thread object. it
|
||||||
|
// is harmless to call init() multiple times.
|
||||||
|
static void init();
|
||||||
|
|
||||||
// the calling thread sleeps for the given number of seconds. if
|
// the calling thread sleeps for the given number of seconds. if
|
||||||
// timeout <= 0.0 then the call returns immediately. if timeout
|
// timeout <= 0.0 then the call returns immediately. if timeout
|
||||||
// == 0.0 then the calling thread yields the CPU.
|
// == 0.0 then the calling thread yields the CPU.
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#include "CThreadRep.h"
|
#include "CThreadRep.h"
|
||||||
#include "CThread.h"
|
#include "CThread.h"
|
||||||
#include "XThread.h"
|
#include "CMutex.h"
|
||||||
#include "CLock.h"
|
#include "CLock.h"
|
||||||
|
#include "XThread.h"
|
||||||
#include "IJob.h"
|
#include "IJob.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
@ -16,7 +17,7 @@ class XThreadUnavailable { };
|
||||||
// CThreadRep
|
// CThreadRep
|
||||||
//
|
//
|
||||||
|
|
||||||
CMutex CThreadRep::s_mutex;
|
CMutex* CThreadRep::s_mutex = NULL;
|
||||||
CThreadRep* CThreadRep::s_head = NULL;
|
CThreadRep* CThreadRep::s_head = NULL;
|
||||||
|
|
||||||
CThreadRep::CThreadRep() : m_prev(NULL),
|
CThreadRep::CThreadRep() : m_prev(NULL),
|
||||||
|
@ -26,6 +27,7 @@ CThreadRep::CThreadRep() : m_prev(NULL),
|
||||||
m_userData(NULL)
|
m_userData(NULL)
|
||||||
{
|
{
|
||||||
// note -- s_mutex must be locked on entry
|
// note -- s_mutex must be locked on entry
|
||||||
|
assert(s_mutex != NULL);
|
||||||
|
|
||||||
// initialize stuff
|
// initialize stuff
|
||||||
init();
|
init();
|
||||||
|
@ -65,6 +67,7 @@ CThreadRep::CThreadRep(IJob* job, void* userData) :
|
||||||
m_userData(userData)
|
m_userData(userData)
|
||||||
{
|
{
|
||||||
assert(m_job != NULL);
|
assert(m_job != NULL);
|
||||||
|
assert(s_mutex != NULL);
|
||||||
|
|
||||||
// create a thread rep for the main thread if the current thread
|
// create a thread rep for the main thread if the current thread
|
||||||
// is unknown. note that this might cause multiple "main" threads
|
// is unknown. note that this might cause multiple "main" threads
|
||||||
|
@ -75,7 +78,7 @@ CThreadRep::CThreadRep(IJob* job, void* userData) :
|
||||||
init();
|
init();
|
||||||
|
|
||||||
// hold mutex while we create the thread
|
// hold mutex while we create the thread
|
||||||
CLock lock(&s_mutex);
|
CLock lock(s_mutex);
|
||||||
|
|
||||||
// start the thread. throw if it doesn't start.
|
// start the thread. throw if it doesn't start.
|
||||||
#if defined(CONFIG_PTHREADS)
|
#if defined(CONFIG_PTHREADS)
|
||||||
|
@ -124,15 +127,22 @@ CThreadRep::~CThreadRep()
|
||||||
fini();
|
fini();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CThreadRep::initThreads()
|
||||||
|
{
|
||||||
|
if (s_mutex == NULL) {
|
||||||
|
s_mutex = new CMutex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CThreadRep::ref()
|
void CThreadRep::ref()
|
||||||
{
|
{
|
||||||
CLock lock(&s_mutex);
|
CLock lock(s_mutex);
|
||||||
++m_refCount;
|
++m_refCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CThreadRep::unref()
|
void CThreadRep::unref()
|
||||||
{
|
{
|
||||||
CLock lock(&s_mutex);
|
CLock lock(s_mutex);
|
||||||
if (--m_refCount == 0) {
|
if (--m_refCount == 0) {
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
@ -140,7 +150,7 @@ void CThreadRep::unref()
|
||||||
|
|
||||||
bool CThreadRep::enableCancel(bool enable)
|
bool CThreadRep::enableCancel(bool enable)
|
||||||
{
|
{
|
||||||
CLock lock(&s_mutex);
|
CLock lock(s_mutex);
|
||||||
const bool old = m_cancellable;
|
const bool old = m_cancellable;
|
||||||
m_cancellable = enable;
|
m_cancellable = enable;
|
||||||
return old;
|
return old;
|
||||||
|
@ -148,7 +158,7 @@ bool CThreadRep::enableCancel(bool enable)
|
||||||
|
|
||||||
bool CThreadRep::isCancellable() const
|
bool CThreadRep::isCancellable() const
|
||||||
{
|
{
|
||||||
CLock lock(&s_mutex);
|
CLock lock(s_mutex);
|
||||||
return (m_cancellable && !m_cancelling);
|
return (m_cancellable && !m_cancelling);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,6 +176,8 @@ void* CThreadRep::getUserData() const
|
||||||
|
|
||||||
CThreadRep* CThreadRep::getCurrentThreadRep()
|
CThreadRep* CThreadRep::getCurrentThreadRep()
|
||||||
{
|
{
|
||||||
|
assert(s_mutex != NULL);
|
||||||
|
|
||||||
#if defined(CONFIG_PTHREADS)
|
#if defined(CONFIG_PTHREADS)
|
||||||
const pthread_t thread = pthread_self();
|
const pthread_t thread = pthread_self();
|
||||||
#elif defined(CONFIG_PLATFORM_WIN32)
|
#elif defined(CONFIG_PLATFORM_WIN32)
|
||||||
|
@ -173,7 +185,7 @@ CThreadRep* CThreadRep::getCurrentThreadRep()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// lock list while we search
|
// lock list while we search
|
||||||
CLock lock(&s_mutex);
|
CLock lock(s_mutex);
|
||||||
|
|
||||||
// search
|
// search
|
||||||
CThreadRep* scan = s_head;
|
CThreadRep* scan = s_head;
|
||||||
|
@ -207,7 +219,7 @@ void CThreadRep::doThreadFunc()
|
||||||
setPriority(1);
|
setPriority(1);
|
||||||
|
|
||||||
// wait for parent to initialize this object
|
// wait for parent to initialize this object
|
||||||
{ CLock lock(&s_mutex); }
|
{ CLock lock(s_mutex); }
|
||||||
|
|
||||||
void* result = NULL;
|
void* result = NULL;
|
||||||
try {
|
try {
|
||||||
|
@ -263,12 +275,13 @@ void CThreadRep::sleep(double timeout)
|
||||||
struct timespec t;
|
struct timespec t;
|
||||||
t.tv_sec = (long)timeout;
|
t.tv_sec = (long)timeout;
|
||||||
t.tv_nsec = (long)(1000000000.0 * (timeout - (double)t.tv_sec));
|
t.tv_nsec = (long)(1000000000.0 * (timeout - (double)t.tv_sec));
|
||||||
nanosleep(&t, NULL);
|
while (nanosleep(&t, &t) < 0)
|
||||||
|
testCancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CThreadRep::cancel()
|
void CThreadRep::cancel()
|
||||||
{
|
{
|
||||||
CLock lock(&s_mutex);
|
CLock lock(s_mutex);
|
||||||
if (m_cancellable && !m_cancelling) {
|
if (m_cancellable && !m_cancelling) {
|
||||||
m_cancel = true;
|
m_cancel = true;
|
||||||
|
|
||||||
|
@ -281,7 +294,7 @@ void CThreadRep::testCancel()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
// prevent further cancellation
|
// prevent further cancellation
|
||||||
CLock lock(&s_mutex);
|
CLock lock(s_mutex);
|
||||||
if (!m_cancel || !m_cancellable || m_cancelling)
|
if (!m_cancel || !m_cancellable || m_cancelling)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -303,14 +316,14 @@ bool CThreadRep::wait(CThreadRep* target, double timeout)
|
||||||
if (target->isExited())
|
if (target->isExited())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (timeout > 0.0) {
|
if (timeout != 0.0) {
|
||||||
CStopwatch timer;
|
CStopwatch timer;
|
||||||
do {
|
do {
|
||||||
sleep(0.05);
|
sleep(0.05);
|
||||||
testCancel();
|
testCancel();
|
||||||
if (target->isExited())
|
if (target->isExited())
|
||||||
return true;
|
return true;
|
||||||
} while (timer.getTime() <= timeout);
|
} while (timeout < 0.0 || timer.getTime() <= timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -323,7 +336,7 @@ void CThreadRep::setPriority(int)
|
||||||
|
|
||||||
bool CThreadRep::isExited() const
|
bool CThreadRep::isExited() const
|
||||||
{
|
{
|
||||||
CLock lock(&s_mutex);
|
CLock lock(s_mutex);
|
||||||
return m_exit;
|
return m_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,7 +354,7 @@ void* CThreadRep::threadFunc(void* arg)
|
||||||
rep->unref();
|
rep->unref();
|
||||||
|
|
||||||
// mark as terminated
|
// mark as terminated
|
||||||
CLock lock(&s_mutex);
|
CLock lock(s_mutex);
|
||||||
rep->m_exit = true;
|
rep->m_exit = true;
|
||||||
|
|
||||||
// terminate the thread
|
// terminate the thread
|
||||||
|
@ -400,7 +413,7 @@ void CThreadRep::testCancel()
|
||||||
|
|
||||||
{
|
{
|
||||||
// ignore if disabled or already cancelling
|
// ignore if disabled or already cancelling
|
||||||
CLock lock(&s_mutex);
|
CLock lock(s_mutex);
|
||||||
if (!m_cancellable || m_cancelling)
|
if (!m_cancellable || m_cancelling)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef CTHREADREP_H
|
#ifndef CTHREADREP_H
|
||||||
#define CTHREADREP_H
|
#define CTHREADREP_H
|
||||||
|
|
||||||
#include "CMutex.h"
|
|
||||||
#include "BasicTypes.h"
|
#include "BasicTypes.h"
|
||||||
|
|
||||||
#if defined(CONFIG_PTHREADS)
|
#if defined(CONFIG_PTHREADS)
|
||||||
|
@ -10,6 +9,7 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class CMutex;
|
||||||
class IJob;
|
class IJob;
|
||||||
|
|
||||||
class CThreadRep {
|
class CThreadRep {
|
||||||
|
@ -18,6 +18,9 @@ class CThreadRep {
|
||||||
|
|
||||||
// manipulators
|
// manipulators
|
||||||
|
|
||||||
|
// initialize the thread library
|
||||||
|
static void initThreads();
|
||||||
|
|
||||||
// change ref count
|
// change ref count
|
||||||
void ref();
|
void ref();
|
||||||
void unref();
|
void unref();
|
||||||
|
@ -92,7 +95,7 @@ class CThreadRep {
|
||||||
CThreadRep& operator=(const CThreadRep&);
|
CThreadRep& operator=(const CThreadRep&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static CMutex s_mutex;
|
static CMutex* s_mutex;
|
||||||
static CThreadRep* s_head;
|
static CThreadRep* s_head;
|
||||||
|
|
||||||
CThreadRep* m_prev;
|
CThreadRep* m_prev;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "CTimerThread.h"
|
#include "CTimerThread.h"
|
||||||
#include "CThread.h"
|
#include "CThread.h"
|
||||||
#include "TMethodJob.h"
|
#include "TMethodJob.h"
|
||||||
|
#include "CLog.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -24,7 +25,9 @@ CTimerThread::~CTimerThread()
|
||||||
|
|
||||||
void CTimerThread::timer(void*)
|
void CTimerThread::timer(void*)
|
||||||
{
|
{
|
||||||
|
log((CLOG_DEBUG "timeout in %f seconds", m_timeout));
|
||||||
CThread::sleep(m_timeout);
|
CThread::sleep(m_timeout);
|
||||||
|
log((CLOG_DEBUG "timeout"));
|
||||||
m_callingThread->cancel();
|
m_callingThread->cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
#include "CProtocolUtil.h"
|
#include "CProtocolUtil.h"
|
||||||
#include "ISecondaryScreen.h"
|
#include "ISecondaryScreen.h"
|
||||||
#include "ProtocolTypes.h"
|
#include "ProtocolTypes.h"
|
||||||
|
#include "CThread.h"
|
||||||
#include "CTimerThread.h"
|
#include "CTimerThread.h"
|
||||||
#include "XSynergy.h"
|
#include "XSynergy.h"
|
||||||
|
#include "TMethodJob.h"
|
||||||
#include "CLog.h"
|
#include "CLog.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -19,15 +21,24 @@ CClient::CClient(const CString& clientName) :
|
||||||
m_output(NULL),
|
m_output(NULL),
|
||||||
m_screen(NULL)
|
m_screen(NULL)
|
||||||
{
|
{
|
||||||
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
CClient::~CClient()
|
CClient::~CClient()
|
||||||
{
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
void CClient::run(const CNetworkAddress& serverAddress)
|
||||||
|
{
|
||||||
|
m_serverAddress = &serverAddress;
|
||||||
|
CThread thread(new TMethodJob<CClient>(this, &CClient::runSession));
|
||||||
|
thread.wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "CTCPSocket.h"
|
#include "CTCPSocket.h"
|
||||||
#include "CXWindowsSecondaryScreen.h"
|
#include "CXWindowsSecondaryScreen.h"
|
||||||
void CClient::run(const CNetworkAddress& serverAddress)
|
void CClient::runSession(void*)
|
||||||
{
|
{
|
||||||
log((CLOG_DEBUG "starting client \"%s\"", m_name.c_str()));
|
log((CLOG_DEBUG "starting client \"%s\"", m_name.c_str()));
|
||||||
|
|
||||||
|
@ -41,7 +52,7 @@ void CClient::run(const CNetworkAddress& serverAddress)
|
||||||
// create socket and attempt to connect to server
|
// create socket and attempt to connect to server
|
||||||
log((CLOG_DEBUG "connecting to server"));
|
log((CLOG_DEBUG "connecting to server"));
|
||||||
socket.reset(new CTCPSocket()); // FIXME -- use factory
|
socket.reset(new CTCPSocket()); // FIXME -- use factory
|
||||||
socket->connect(serverAddress);
|
socket->connect(*m_serverAddress);
|
||||||
log((CLOG_INFO "connected to server"));
|
log((CLOG_INFO "connected to server"));
|
||||||
|
|
||||||
// get the input and output streams
|
// get the input and output streams
|
||||||
|
|
|
@ -22,6 +22,8 @@ class CClient {
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void runSession(void*);
|
||||||
|
|
||||||
// message handlers
|
// message handlers
|
||||||
void onEnter();
|
void onEnter();
|
||||||
void onLeave();
|
void onLeave();
|
||||||
|
@ -53,6 +55,7 @@ class CClient {
|
||||||
IInputStream* m_input;
|
IInputStream* m_input;
|
||||||
IOutputStream* m_output;
|
IOutputStream* m_output;
|
||||||
ISecondaryScreen* m_screen;
|
ISecondaryScreen* m_screen;
|
||||||
|
const CNetworkAddress* m_serverAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,6 +52,7 @@ void CProtocolUtil::readf(IInputStream* stream,
|
||||||
{
|
{
|
||||||
assert(stream != NULL);
|
assert(stream != NULL);
|
||||||
assert(fmt != NULL);
|
assert(fmt != NULL);
|
||||||
|
log((CLOG_DEBUG "readf(%s)", fmt));
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
@ -93,6 +94,7 @@ void CProtocolUtil::readf(IInputStream* stream,
|
||||||
static_cast<UInt32>(buffer[3]);
|
static_cast<UInt32>(buffer[3]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
log((CLOG_DEBUG "readf: read %d byte integer: %d (0x%x)", len, *v, *v));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +131,7 @@ void CProtocolUtil::readf(IInputStream* stream,
|
||||||
}
|
}
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
log((CLOG_DEBUG "readf: read %d byte string: %.*s", len, len, sBuffer));
|
||||||
|
|
||||||
// save the data
|
// save the data
|
||||||
CString* dst = va_arg(args, CString*);
|
CString* dst = va_arg(args, CString*);
|
||||||
|
@ -159,6 +162,7 @@ void CProtocolUtil::readf(IInputStream* stream,
|
||||||
|
|
||||||
// verify match
|
// verify match
|
||||||
if (buffer[0] != *fmt) {
|
if (buffer[0] != *fmt) {
|
||||||
|
log((CLOG_DEBUG "readf: format mismatch: %c vs %c", *fmt, buffer[0]));
|
||||||
throw XIOReadMismatch();
|
throw XIOReadMismatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,6 +326,7 @@ void CProtocolUtil::read(IInputStream* stream,
|
||||||
|
|
||||||
// bail if stream has hungup
|
// bail if stream has hungup
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
|
log((CLOG_DEBUG "unexpected disconnect in readf(), %d bytes left", count));
|
||||||
throw XIOEndOfStream();
|
throw XIOEndOfStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,14 @@ void CServerProtocol1_0::run()
|
||||||
|
|
||||||
// verify we got an entire code
|
// verify we got an entire code
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
|
log((CLOG_NOTE "client \"%s\" disconnected", getClient().c_str()));
|
||||||
|
|
||||||
// client hungup
|
// client hungup
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (n != 4) {
|
if (n != 4) {
|
||||||
|
log((CLOG_ERR "incomplete message from \"%s\": %d bytes", getClient().c_str(), n));
|
||||||
|
|
||||||
// client sent an incomplete message
|
// client sent an incomplete message
|
||||||
throw XBadClient();
|
throw XBadClient();
|
||||||
}
|
}
|
||||||
|
@ -47,6 +51,8 @@ void CServerProtocol1_0::run()
|
||||||
}
|
}
|
||||||
// FIXME -- more message here
|
// FIXME -- more message here
|
||||||
else {
|
else {
|
||||||
|
log((CLOG_ERR "unknown message from client \"%s\"", getClient().c_str()));
|
||||||
|
|
||||||
// unknown message
|
// unknown message
|
||||||
throw XBadClient();
|
throw XBadClient();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
#include "CClient.h"
|
#include "CClient.h"
|
||||||
#include "CNetworkAddress.h"
|
#include "CNetworkAddress.h"
|
||||||
|
#include "CThread.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
CThread::init();
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
fprintf(stderr, "usage: %s <hostname>\n", argv[0]);
|
fprintf(stderr, "usage: %s <hostname>\n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
#include "CServer.h"
|
#include "CServer.h"
|
||||||
#include "CScreenMap.h"
|
#include "CScreenMap.h"
|
||||||
|
#include "CThread.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
CThread::init();
|
||||||
|
|
||||||
if (argc != 1) {
|
if (argc != 1) {
|
||||||
fprintf(stderr, "usage: %s\n", argv[0]);
|
fprintf(stderr, "usage: %s\n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
Loading…
Reference in New Issue