1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
map<int, CONNECTION> connections;
volatile CONNECTION* n2i;
CRITICAL_SECTION cs;
DWORD WINAPI _worker_listener_rel( void* in ){
lrc++;
EnterCriticalSection(&cs);
if(!n2i)
return 0;
CONNECTION* c = (CONNECTION*)n2i;//Make a working pointer
LPWSTR wndname = (LPWSTR)malloc(124);
wsprintfW(wndname, L"RELIABLE_LISTENER#%u", lrc);
c->wnd = CreateWindowEx(NULL,
L"NETRELLISTENERCLS",
wndname,
WS_OVERLAPPEDWINDOW,
300,
300,
500,
400,
NULL,
NULL,
appinst,
NULL);
if(!c->wnd){
ONERR(0, 0, (*c));
return 0;
}
n2i = 0;
LeaveCriticalSection(&cs);
int result;
c->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(c->sock==INVALID_SOCKET){
ONERR( (int)c->wnd, WSAGetLastError(), (*c));
return 0;
};
connections.insert(pair<int, CONNECTION>((int)c->wnd, *c));//Make a copy
WSAAsyncSelect(c->sock,c->wnd, WM_WSAASYNC, FD_READ | FD_ACCEPT | FD_CLOSE );
//Bind and listen
result = bind(c->sock, (SOCKADDR*) &c->addr, sizeof(c->addr));
if(result==SOCKET_ERROR){
ONERR( (int)c->wnd, WSAGetLastError(), (*c));
return 0;
}
result = listen(c->sock, SOMAXCONN);
if(result==SOCKET_ERROR){
ONERR( (int)c->wnd, WSAGetLastError(), (*c));
return 0;
}
ONINIT( (int)c->wnd, (*c) );
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
if(msg.message==WM_KILLCONNECTION||msg.message==WM_QUIT){
break;
}
DispatchMessage(&msg);
}
//Clean self and all subconns
connections.erase((int)c->wnd);
return 1;
}
int listener(unsigned short port, char flags, DATAFP onrecv, GENERALFP oninit, GENERALFP onshutdown, ERRORFP onerr){
if(!inited){
lasterr = 0;
return 0;
}
CONNECTION* server = new CONNECTION;
server->onrecv = onrecv;//If this is null than we'll only do sending
server->oninit = oninit;
server->onshutdown = onshutdown;
server->onerror = onerr;
server->flags = flags;
server->pv.a = (int*)malloc(sizeof(int)*participants_alloc);
server->pv.pm = participants_alloc;
server->pv.pc = 0;
EnterCriticalSection(&cs);
n2i = server;
server->addr.sin_family = AF_INET;
server->addr.sin_port = htons( port );
server->addr.sin_addr.s_addr = inet_addr( "0.0.0.0" );
server->latency = -1;//Not connected
server->thread = CreateThread( NULL, 0,
(LPTHREAD_START_ROUTINE)(flags&LF_RELIABLE||flags&(!LF_RELIABLE|!LF_TIMECRIT))?_worker_listener_rel:_worker_listener_tc,
(LPVOID)NULL, 0, &(server->tid));
if(server->thread==NULL){
n2i = 0;
LeaveCriticalSection(&cs);
lasterr = GetLastError();
return 0;
}
LeaveCriticalSection(&cs);//Let the thread work;
EnterCriticalSection(&cs);//When we get control again (best case we get it next) connection will be initialised
LeaveCriticalSection(&cs);//Make sure we dont lock
/*Solution
while(n2i!=0){
Sleep(1);
EnterCriticalSection(&cs);//When we get control again (best case we get it next) connection will be initialised
LeaveCriticalSection(&cs);//Make sure we dont lock
}
return (int)server->wnd; //And return!
} */
|