Browse files

BaseSocket.cpp added (fire_xxx funtion added)

rename IOService::base() => coreHandle()
Windows IOCP more stable using IOService::isStopped
  • Loading branch information...
1 parent 48766f0 commit 52054bd8c8c83e13c6e1a4a39df2d954f790b3e6 @gunoodaddy committed Jan 16, 2012
View
50 src/BaseSocket.cpp
@@ -0,0 +1,50 @@
+#include "Coconut.h"
+#include "BaseSocket.h"
+#include "IOService.h"
+#include "ThreadUtil.h"
+
+namespace coconut {
+
+void BaseSocket::fire_onSocket_Initialized() {
+ lockHandler_.lock();
+ if(handler_ && ioService_->isStopped() == false)
+ handler_->onSocket_Initialized();
+ lockHandler_.unlock();
+}
+
+void BaseSocket::fire_onSocket_Connected() {
+ lockHandler_.lock();
+ if(handler_ && ioService_->isStopped() == false)
+ handler_->onSocket_Connected();
+ lockHandler_.unlock();
+}
+
+void BaseSocket::fire_onSocket_Error(int error, const char *strerror) {
+ lockHandler_.lock();
+ if(handler_ && ioService_->isStopped() == false)
+ handler_->onSocket_Error(error, strerror);
+ lockHandler_.unlock();
+}
+
+void BaseSocket::fire_onSocket_ReadEvent(int fd) {
+ lockHandler_.lock();
+ if(handler_ && ioService_->isStopped() == false)
+ handler_->onSocket_ReadEvent(fd);
+ lockHandler_.unlock();
+}
+
+void BaseSocket::fire_onSocket_ReadFrom(const void *data, int size, struct sockaddr_in * sin) {
+ lockHandler_.lock();
+ if(handler_ && ioService_->isStopped() == false)
+ handler_->onSocket_ReadFrom(data, size, sin);
+ lockHandler_.unlock();
+}
+
+void BaseSocket::fire_onSocket_Close() {
+ lockHandler_.lock();
+ if(handler_ && ioService_->isStopped() == false)
+ handler_->onSocket_Close();
+ lockHandler_.unlock();
+}
+
+}
View
12 src/BaseSocket.h 100644 → 100755
@@ -17,6 +17,7 @@
#else
#include <arpa/inet.h>
#endif
+#include "ThreadUtil.h"
namespace coconut {
@@ -81,7 +82,9 @@ class COCONUT_API BaseSocket : public BaseVirtualTransport {
}
void setEventHandler(EventHandler *handler) {
+ lockHandler_.lock();
handler_ = handler;
+ lockHandler_.unlock();
}
EventHandler *eventHandler() {
@@ -118,12 +121,21 @@ class COCONUT_API BaseSocket : public BaseVirtualTransport {
return -1;
}
+public:
+ void fire_onSocket_Initialized();
+ void fire_onSocket_Connected();
+ void fire_onSocket_Error(int error, const char *strerror);
+ void fire_onSocket_ReadEvent(int fd);
+ void fire_onSocket_ReadFrom(const void *data, int size, struct sockaddr_in * sin);
+ void fire_onSocket_Close();
+
protected:
boost::shared_ptr<IOService> ioService_;
SocketType type_;
SocketState state_;
EventHandler *handler_;
std::string lastErrorString_;
+ Mutex lockHandler_;
};
}
View
2 src/ConnectionListener.cpp
@@ -81,7 +81,7 @@ class ConnectionListenerImpl {
}
- listener_ = evconnlistener_new_bind(owner_->ioService()->base(), accept_conn_cb, this,
+ listener_ = evconnlistener_new_bind(owner_->ioService()->coreHandle(), accept_conn_cb, this,
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1,
sinptr, addrlen);
View
2 src/DNSResolver.cpp
@@ -48,7 +48,7 @@ class DNSResolverImpl {
bool resolve(const char *host, struct sockaddr_in *sin, DNSResolver::EventHandler* handler, void *ptr) {
if(NULL == dnsbase_) {
- dnsbase_ = evdns_base_new(ioService_->base(), 1);
+ dnsbase_ = evdns_base_new(ioService_->coreHandle(), 1);
}
std::map<std::string, struct dns_context_t *>::iterator it = mapcontext_.find(host);
View
4 src/DeferredCaller.cpp
@@ -19,7 +19,7 @@ class DeferredCallerImpl {
DeferredCallerImpl(boost::shared_ptr<IOService> ioService)
: ioService_(ioService), eventDeferred_(NULL) {
- eventDeferred_ = event_new(ioService->base(), -1, EV_READ|EV_PERSIST, cb_func, this);
+ eventDeferred_ = event_new(ioService->coreHandle(), -1, EV_READ|EV_PERSIST, cb_func, this);
}
~DeferredCallerImpl() {
@@ -51,7 +51,7 @@ class DeferredCallerImpl {
event_free(eventDeferred_);
eventDeferred_ = NULL;
}
- eventDeferred_ = event_new(ioService->base(), -1, EV_READ|EV_PERSIST, cb_func, this);
+ eventDeferred_ = event_new(ioService->coreHandle(), -1, EV_READ|EV_PERSIST, cb_func, this);
}
void deferredCall(deferedMethod_t func) {
View
4 src/HttpRequest.cpp
@@ -375,14 +375,14 @@ class HttpRequestImpl {
if(port < 0)
port = 80;
LOG_TRACE("Http Connection Making.. : %s:%d", evhttp_uri_get_host(evuri_), port);
- evcon_ = evhttp_connection_base_new(ioService_->base(), dnsbase_, evhttp_uri_get_host(evuri_), port);
+ evcon_ = evhttp_connection_base_new(ioService_->coreHandle(), dnsbase_, evhttp_uri_get_host(evuri_), port);
assert(evcon_ && "evhttp_connection can not be allocated");
evhttp_connection_set_timeout(evcon_, timeout_);
}
void startRequest(std::string &uri) {
- dnsbase_ = evdns_base_new(ioService_->base(), 1);
+ dnsbase_ = evdns_base_new(ioService_->coreHandle(), 1);
assert(dnsbase_ && "evdns_base can not be allocated");
evhttp_make_request(evcon_, req_, method_ == HTTP_POST ? EVHTTP_REQ_POST : EVHTTP_REQ_GET, uri.c_str());
View
18 src/IOService.cpp
@@ -136,11 +136,15 @@ class IOServiceImpl {
#endif
}
+ bool isStopped() {
+ return loopExitFlag_;
+ }
+
BaseIOServiceContainer *ioServiceContainer() {
return ioServiceContainer_;
}
- struct event_base * base() {
+ struct event_base * coreHandle() {
return base_;
}
@@ -213,7 +217,7 @@ class IOServiceImpl {
#if defined(WIN32)
void turnOnIOCP(size_t cpuCnt) {
- cpuCnt = cpuCnt;
+ cpuCnt_ = cpuCnt;
enabledIOCP_ = true;
}
#endif
@@ -223,6 +227,7 @@ class IOServiceImpl {
LOG_DEBUG("IOService stop eventloop..");
struct timeval tv = MAKE_TIMEVAL_MSEC(10);
event_base_loopexit(base_, &tv);
+ loopExitFlag_ = true;
//event_base_loopbreak(base_);
}
}
@@ -289,7 +294,6 @@ class IOServiceImpl {
void dispatchEvent() {
event_base_dispatch(base_);
- loopExitFlag_ = true;
LOG_INFO("finished dispatch event.. this = %p", this);
// TODO gracefully program exit logic need...
//assert(false && "event loop exit???? why?");
@@ -376,12 +380,16 @@ bool IOService::isCalledInMountedThread() {
return impl_->isCalledInMountedThread();
}
+bool IOService::isStopped() {
+ return impl_->isStopped();
+}
+
BaseIOServiceContainer *IOService::ioServiceContainer() {
return impl_->ioServiceContainer();
}
-struct event_base * IOService::base() {
- return impl_->base();
+struct event_base * IOService::coreHandle() {
+ return impl_->coreHandle();
}
Mutex & IOService::mutex() {
View
9 src/IOService.h 100644 → 100755
@@ -6,14 +6,17 @@
#include <boost/thread.hpp>
#endif
-//#define __USE_PTHREAD__
#ifdef __USE_PTHREAD__
#include <pthread.h>
#endif
#include "ThreadUtil.h"
#define ScopedIOServiceLock(ioService) ScopedMutexLock(ioService->mutex())
+#define CHECK_IOSERVICE_STOP_VOID_RETURN(ioService) \
+ if(ioService->isStopped()) \
+ return;
+
struct event_base;
namespace coconut {
@@ -46,10 +49,10 @@ class COCONUT_API IOService : public boost::enable_shared_from_this<IOService> {
void stop();
bool isCalledInMountedThread();
+ bool isStopped();
BaseIOServiceContainer *ioServiceContainer();
- struct event_base * base();
- void triggerEvent();
+ struct event_base * coreHandle();
Mutex &mutex();
#if defined(WIN32)
View
1 src/IOServiceContainer.cpp 100644 → 100755
@@ -24,6 +24,7 @@ void IOServiceContainer::turnOnIOCP(size_t cpuCnt) {
throw Exception("iocp is turned on, but your thread count setting is not 0");
}
+ cpuCnt_ = cpuCnt;
if(cpuCnt_ == 0)
cpuCnt_ = 1;
View
1 src/IOServiceContainer.h 100644 → 100755
@@ -11,6 +11,7 @@ class COCONUT_API IOServiceContainer : public BaseIOServiceContainer {
IOServiceContainer(int threadCount = 0) : threadCount_(threadCount)
#if defined(WIN32)
, iocpEnabled_(false)
+ , cpuCnt_(0)
#endif
{
}
View
12 src/Logger.h
@@ -47,12 +47,14 @@ typedef struct COCONUT_API LogHookCallback {
void (*fatal) (LogLevel level, const char *fileName, int fileLine, const char *functionName, const char *logmsg);
}LogHookCallback;
-void setLogLevel(LogLevel level);
-void setLogHookFunctionCallback(LogHookCallback callback);
-LogLevel currentLogLevel();
+COCONUT_API void setLogLevel(LogLevel level);
-void logprintf(const char *file, const char *function, int line, LogLevel level, const char * format, ...);
+COCONUT_API void setLogHookFunctionCallback(LogHookCallback callback);
-void hexdump(const unsigned char *data, const int len, FILE * fp);
+COCONUT_API LogLevel currentLogLevel();
+
+COCONUT_API void logprintf(const char *file, const char *function, int line, LogLevel level, const char * format, ...);
+
+COCONUT_API void hexdump(const unsigned char *data, const int len, FILE * fp);
} } // end of namespace coconut / logger
View
1 src/Makefile.am
@@ -14,6 +14,7 @@ libcoconut_la_SOURCES = \
Timer.cpp \
DNSResolver.cpp \
BufferedTransport.cpp \
+ BaseSocket.cpp \
TcpSocket.cpp \
UdpSocket.cpp \
ConnectionListener.cpp \
View
14 src/Makefile.in
@@ -81,12 +81,12 @@ LTLIBRARIES = $(lib_LTLIBRARIES)
libcoconut_la_LIBADD =
am_libcoconut_la_OBJECTS = kbuffer.lo Coconut.lo Logger.lo \
IOService.lo IOServiceContainer.lo DeferredCaller.lo Timer.lo \
- DNSResolver.lo BufferedTransport.lo TcpSocket.lo UdpSocket.lo \
- ConnectionListener.lo RedisRequest.lo RedisResponse.lo \
- HttpRequest.lo BaseProtocol.lo LineProtocol.lo \
- FrameProtocol.lo FileDescriptorProtocol.lo BaseController.lo \
- BaseControllerEvent.lo ClientController.lo ServerController.lo \
- LineController.lo FrameController.lo \
+ DNSResolver.lo BufferedTransport.lo BaseSocket.lo TcpSocket.lo \
+ UdpSocket.lo ConnectionListener.lo RedisRequest.lo \
+ RedisResponse.lo HttpRequest.lo BaseProtocol.lo \
+ LineProtocol.lo FrameProtocol.lo FileDescriptorProtocol.lo \
+ BaseController.lo BaseControllerEvent.lo ClientController.lo \
+ ServerController.lo LineController.lo FrameController.lo \
FileDescriptorController.lo HttpRequestController.lo \
RedisController.lo NetworkHelper.lo
libcoconut_la_OBJECTS = $(am_libcoconut_la_OBJECTS)
@@ -258,6 +258,7 @@ libcoconut_la_SOURCES = \
Timer.cpp \
DNSResolver.cpp \
BufferedTransport.cpp \
+ BaseSocket.cpp \
TcpSocket.cpp \
UdpSocket.cpp \
ConnectionListener.cpp \
@@ -395,6 +396,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BaseController.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BaseControllerEvent.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BaseProtocol.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BaseSocket.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BufferedTransport.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClientController.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Coconut.Plo@am__quote@
View
2 src/RedisRequest.cpp
@@ -66,7 +66,7 @@ class RedisRequestImpl {
}
redisContext_->data = this;
- redisLibeventAttach(redisContext_, ioService_->base());
+ redisLibeventAttach(redisContext_, ioService_->coreHandle());
redisAsyncSetConnectCallback(redisContext_, connectCallback);
redisAsyncSetDisconnectCallback(redisContext_, disconnectCallback);
}
View
71 src/TcpSocket.cpp 100644 → 100755
@@ -63,6 +63,8 @@ class TcpSocketImpl : private Timer::EventHandler {
static void bufevent_cb(struct bufferevent *bev, short events, void *ptr) {
TcpSocketImpl *SELF = (TcpSocketImpl *)ptr;
+ CHECK_IOSERVICE_STOP_VOID_RETURN(SELF->ioService());
+
if (events & BEV_EVENT_CONNECTED) {
bufferevent_enable(bev, EV_READ|EV_WRITE);
SELF->fire_onSocket_Connected();
@@ -76,6 +78,7 @@ class TcpSocketImpl : private Timer::EventHandler {
static void event_cb(coconut_socket_t fd, short what, void *arg) {
TcpSocketImpl *SELF = (TcpSocketImpl *)arg;
+ CHECK_IOSERVICE_STOP_VOID_RETURN(SELF->ioService());
if(what & EV_READ) {
SELF->_onReadEvent(fd);
@@ -100,15 +103,18 @@ class TcpSocketImpl : private Timer::EventHandler {
hexdump((const unsigned char*)data, buffer_len, stdout);
TcpSocketImpl *SELF = (TcpSocketImpl *)ptr;
+ CHECK_IOSERVICE_STOP_VOID_RETURN(SELF->ioService());
SELF->fire_onSocket_Read(data, buffer_len);
evbuffer_drain(readBuffer, buffer_len);
#elif defined(READ_MODE_3)
TcpSocketImpl *SELF = (TcpSocketImpl *)ptr;
+ CHECK_IOSERVICE_STOP_VOID_RETURN(SELF->ioService());
SELF->fire_onSocket_ReadEvent(bufferevent_getfd(bev));
#else
// WORST PERFOMANCE!!!
TcpSocketImpl *SELF = (TcpSocketImpl *)ptr;
+ CHECK_IOSERVICE_STOP_VOID_RETURN(SELF->ioService());
struct evbuffer *readBuffer = bufferevent_get_input(bev);
size_t buffer_len = evbuffer_get_length(readBuffer);
char *buffer = new char[buffer_len];
@@ -120,9 +126,14 @@ class TcpSocketImpl : private Timer::EventHandler {
static void timer_cb(coconut_socket_t fd, short what, void *arg) {
TcpSocketImpl *SELF = (TcpSocketImpl *)arg;
+ CHECK_IOSERVICE_STOP_VOID_RETURN(SELF->ioService());
SELF->fire_onSocket_Error(COOKIE_ETIMEDOUT);
}
+public:
+ boost::shared_ptr<IOService> ioService() {
+ return owner_->ioService();
+ }
coconut_socket_t socketFD() {
if(bev_)
@@ -222,7 +233,7 @@ class TcpSocketImpl : private Timer::EventHandler {
_createBufferEvent(-1);
- dnsbase_ = evdns_base_new(owner_->ioService()->base(), 1);
+ dnsbase_ = evdns_base_new(owner_->ioService()->coreHandle(), 1);
int ret = bufferevent_socket_connect_hostname(bev_, dnsbase_, AF_UNSPEC, host_.c_str(), port_);
if(0 != ret) {
@@ -259,29 +270,45 @@ class TcpSocketImpl : private Timer::EventHandler {
void _createEvent(coconut_socket_t fd) {
if(NULL == ev_read_)
- ev_read_ = event_new(owner_->ioService()->base(), fd, EV_READ|EV_PERSIST, event_cb, this);
+ ev_read_ = event_new(owner_->ioService()->coreHandle(), fd, EV_READ|EV_PERSIST, event_cb, this);
if(NULL == ev_write_)
- ev_write_ = event_new(owner_->ioService()->base(), fd, EV_WRITE|EV_PERSIST, event_cb, this);
- owner_->eventHandler()->onSocket_Initialized();
+ ev_write_ = event_new(owner_->ioService()->coreHandle(), fd, EV_WRITE|EV_PERSIST, event_cb, this);
+
+ if(NULL == write_evbuffer_)
+ write_evbuffer_ = evbuffer_new();
+ if(NULL == write_kbuffer_)
+ write_kbuffer_ = kbuffer_new();
+
+ owner_->fire_onSocket_Initialized();
}
void _createBufferEvent(coconut_socket_t fd) {
if(NULL == bev_) {
- bev_ = bufferevent_socket_new(owner_->ioService()->base(), fd, BEV_OPT_CLOSE_ON_FREE);
+ bev_ = bufferevent_socket_new(owner_->ioService()->coreHandle(), fd, BEV_OPT_CLOSE_ON_FREE);
bufferevent_enable(bev_, EV_READ|EV_WRITE);
}
- owner_->eventHandler()->onSocket_Initialized();
- }
-
- void install() {
- ScopedIOServiceLock(owner_->ioService());
+
if(NULL == write_evbuffer_)
write_evbuffer_ = evbuffer_new();
if(NULL == write_kbuffer_)
write_kbuffer_ = kbuffer_new();
+ owner_->fire_onSocket_Initialized();
+ }
+
+ void install() {
+ ScopedIOServiceLock(owner_->ioService());
+
if(bev_) {
bufferevent_setcb(bev_, read_cb, NULL, bufevent_cb, this);
+
+ struct evbuffer *readBuffer = bufferevent_get_input(bev_);
+ if(readBuffer) {
+ size_t buffer_len = evbuffer_get_length(readBuffer);
+ if(buffer_len > 0) {
+ read_cb(bev_, this);
+ }
+ }
}
if(ev_read_) {
event_add(ev_read_, NULL);
@@ -331,6 +358,8 @@ class TcpSocketImpl : private Timer::EventHandler {
return size;
} else {
char *p = (char *)malloc(size);
+ if(NULL == p)
+ return -1;
#if defined(WIN32)
int res = ::recv(socketFD(), (char *)p, size, 0);
#else
@@ -340,6 +369,7 @@ class TcpSocketImpl : private Timer::EventHandler {
data.assign(p, res);
else
checkResponseSocket(res);
+ free(p);
return res;
}
}
@@ -360,7 +390,6 @@ class TcpSocketImpl : private Timer::EventHandler {
#else
int res = ::read(socketFD(), data, size);
#endif
-
if(res <= 0)
checkResponseSocket(res);
return res;
@@ -391,7 +420,7 @@ class TcpSocketImpl : private Timer::EventHandler {
struct evbuffer *output = bufferevent_get_output(bev_);
ret = evbuffer_add(output, data, size);
if(ret == 0) {
- //bufferevent_enable(bev_, EV_READ|EV_WRITE);
+ //bufferevent_enable(bev_, EV_WRITE);
ret = size;
}
} else {
@@ -437,7 +466,6 @@ class TcpSocketImpl : private Timer::EventHandler {
}
}
-
void _onReadEvent(coconut_socket_t fd) {
fire_onSocket_ReadEvent(fd);
}
@@ -474,7 +502,7 @@ class TcpSocketImpl : private Timer::EventHandler {
}
break;
}
- } while(0);
+ } while(false);
if(destroy) {
LOG_FATAL("write error size = %d, reason = %d, fd = %d, errno = %d", size, destroy, socketFD(), EVUTIL_SOCKET_ERROR())
@@ -496,8 +524,9 @@ class TcpSocketImpl : private Timer::EventHandler {
fire_onSocket_Error(COOKIE_ETIMEDOUT);
}
- void fire_onSocket_ReadEvent(int fd) {
- owner_->eventHandler()->onSocket_ReadEvent(fd);
+private: // fire event callback
+ inline void fire_onSocket_ReadEvent(int fd) {
+ owner_->fire_onSocket_ReadEvent(fd);
}
/*
@@ -511,13 +540,13 @@ class TcpSocketImpl : private Timer::EventHandler {
this, socketFD(), owner_->eventHandler(), EVUTIL_SOCKET_ERROR());
_deleteTimer();
owner_->setState(BaseSocket::Disconnected);
- owner_->eventHandler()->onSocket_Close();
+ owner_->fire_onSocket_Close();
close();
}
void fire_onSocket_Error(int error) {
- LOG_DEBUG("fire_onSocket_Error : this = %p, fd = %d, error = %d, %s\n",
- this, socketFD(), EVUTIL_SOCKET_ERROR(), evutil_socket_error_to_string(error));
+ LOG_DEBUG("fire_onSocket_Error : this = %p, fd = %d, error = %d, %s, handler = %p\n",
+ this, socketFD(), EVUTIL_SOCKET_ERROR(), evutil_socket_error_to_string(error), owner_->eventHandler());
errorDetected_ = true;
owner_->setLastErrorString(evutil_socket_error_to_string(error));
@@ -529,7 +558,7 @@ class TcpSocketImpl : private Timer::EventHandler {
}
}
owner_->setState(BaseSocket::Disconnected);
- owner_->eventHandler()->onSocket_Error(error, owner_->lastErrorString());
+ owner_->fire_onSocket_Error(error, owner_->lastErrorString());
close();
}
@@ -559,7 +588,7 @@ class TcpSocketImpl : private Timer::EventHandler {
}
_deleteTimer();
- owner_->eventHandler()->onSocket_Connected();
+ owner_->fire_onSocket_Connected();
}
private:
View
2 src/Timer.cpp
@@ -47,7 +47,7 @@ class TimerImpl {
} else {
LOG_DEBUG("NEW TIMER : ioService = %p id = %d sec = %d.%d\n", owner_->ioService().get(), id, msec/1000, msec % 1000);
context = (struct timer_context_t *)malloc(sizeof(struct timer_context_t));
- context->timer = evtimer_new(owner_->ioService()->base(), timer_cb, context);
+ context->timer = evtimer_new(owner_->ioService()->coreHandle(), timer_cb, context);
mapTimers_.insert(std::map<int, struct timer_context_t *>::value_type(id, context));
}
View
7 src/UdpSocket.cpp
@@ -44,6 +44,7 @@ class UdpSocketImpl : public DNSResolver::EventHandler {
private:
static void event_cb(coconut_socket_t fd, short what, void *arg) {
UdpSocketImpl *SELF = (UdpSocketImpl *)arg;
+ CHECK_IOSERVICE_STOP_VOID_RETURN(SELF->ioService());
if(what & EV_READ) {
char buf[UDP_BUF_SIZE] = {0, };
@@ -57,6 +58,10 @@ class UdpSocketImpl : public DNSResolver::EventHandler {
}
public:
+ boost::shared_ptr<IOService> ioService() {
+ return owner_->ioService();
+ }
+
coconut_socket_t socketFD() {
if(ev_)
return event_get_fd(ev_);
@@ -96,7 +101,7 @@ class UdpSocketImpl : public DNSResolver::EventHandler {
}
}
- ev_ = event_new(owner_->ioService()->base(), sock, EV_READ|EV_PERSIST, event_cb, this);
+ ev_ = event_new(owner_->ioService()->coreHandle(), sock, EV_READ|EV_PERSIST, event_cb, this);
event_add(ev_, NULL); // TODO UDP READ TIMEOUT??
owner_->eventHandler()->onSocket_Initialized();

0 comments on commit 52054bd

Please sign in to comment.