void NetworkManager::AssignTask(void(*callback)()) { int count = GetFreeThread(); if (count != -1) { m_ptrThread[count]->SetThreadBusy(); m_ptrThread[count]->SetFunction(callback); m_ptrThread[count]->SignalWorkEvent(); } }
/*FUNCTION*/ int httpd(int argc, char *argv[], int (*AppInit)(int argc,char *argv[],pHttpdThread pHT,void **AppData), int (*AppStart)(void **AppData), void (*HttpProc)(pHttpdThread pHT,pThreadData ThisThread), int (*FtpProc)(pHttpdThread pHT,pThreadData ThisThread, char *pszCommand) ){ /*noverbatim CUT*/ int addr_size; int i,j,so; int length; struct _fun Functions; struct sockaddr_in server; pThreadData ThisThread; HttpdThread HT; int iState; int cThread; unsigned long iL; #ifdef WIN32 WORD wVersionRequested; WSADATA wsaData; int err; #else int cpid; #endif char *optarg,opt; int OptionIndex; fd_set acceptfds; struct timeval timeout; #ifdef WIN32 wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if( err != 0 ){ fprintf(stderr,"Error initializing the Windows Socket subsystem\n"); exit(1); } #endif HT.server[0].port = HTTPD_PORT; HT.server[0].ip = HTTPD_IP; HT.c_servers = 1; HT.threadmax = CONCURRENT_HITS; HT.listenmax = LISTEN_BACKLOG; HT.server[0].cAllowed = 0; HT.server[0].cDenied = 0; /* init the signal handlerts to SIG_IGN so that a brokern pipe does not kill us */ InitSignalHandlers(); /* This is just a pointer that we guarantee not to be altered. */ HT.AppData = NULL; /* AppInit should return zero on success. */ if( i=AppInit(argc,argv,&HT,&(HT.AppData)) ){ fprintf(stderr,"AppInit returned %d\n",i); exit(i); } OptionIndex = 0; while( (opt = getoptt(argc, argv, "p:h:",&optarg,&OptionIndex)) != ':'){ switch( opt ){ case 'p' : /* you can specify a port number on the command line to bind on */ /* this overrides the configuration port */ HT.server[0].port = atoi(optarg); HT.c_servers = 1; break; case 'h' : /* you can specify a single host IP to bind on */ /* this overrides the configuration ip */ HT.server[0].ip = inet_addr(optarg); HT.c_servers = 1; break; } } for( i=0 ; i < HT.c_servers ; i++ ){ HT.server[i].sock = socket(AF_INET, SOCK_STREAM, 0); so=1; setsockopt(HT.server[i].sock, SOL_SOCKET, SO_REUSEADDR, (char *)(&so),sizeof(i)); if( HT.server[i].sock < 0 ){ fprintf(stderr, "Error at socket"); exit(1); } server.sin_family = AF_INET; server.sin_addr.s_addr = HT.server[i].ip; server.sin_port = htons(HT.server[i].port); for( j=0 ; j<MAXBINDTRIAL ; j++ ){ if( ! bind(HT.server[i].sock, (struct sockaddr *)&server, sizeof(server)) )break; if( j == MAXBINDTRIAL-1 ){ fprintf(stderr, "\nError at bind."); exit(1); } if( j== 0 )fprintf(stderr,"Bind failed on %s:%d, retrying at most %d times\n.", inet_ntoa(server.sin_addr), ntohs(server.sin_port),MAXBINDTRIAL); else fprintf(stderr,"."); if( j%40 == 39 )fprintf(stderr,"\n"); Sleep(BINDSLEEP); } if( j )fprintf(stderr,"\nBind finally successful after %d trials\n",j); length = sizeof(server); if( getsockname(HT.server[i].sock, (struct sockaddr *)&server, &length) ){ fprintf(stderr, "Error at getsockname."); exit(1); } listen(HT.server[i].sock, HT.listenmax); } HT.iState = STATE_NORMAL; if( j=AppStart(&(HT.AppData)) ){ fprintf(stderr,"Appstart returned %d\n",j); exit(j); } HT.threads = (pThreadData)malloc(HT.threadmax*sizeof(ThreadData)); if( HT.threads == NULL ){ fprintf(stderr,"Not enough memory\n"); exit(1); } /* Initialize the list of thread data */ for( i=0 ; i < HT.threadmax ; i++ ){ HT.threads[i].ThreadIndex = i; HT.threads[i].pFunctions = &Functions; HT.threads[i].NextFree = i+1; HT.threads[i].pHT = &HT; } HT.cThread = 0; /* make it dead end */ HT.threads[HT.threadmax-1].NextFree = -1; HT.FirstFreeThread = 0; thread_InitMutex(&(HT.mxFirstFreeThread)); Functions.pGetServerVariable = _GetServerVariable; Functions.pWriteClient = _WriteClient; Functions.pWriteClientText = _WriteClientText; Functions.pReadClient = _ReadClient; Functions.pState = _State; Functions.pContentType = _ContentType; Functions.pHeader = _Header; Functions.pStartBody = _StartBody; Functions.pGetParam = _GetParam; Functions.pPostParam = _PostParam; Functions.pCloseClient = _CloseClient; Functions.pScriptName = _ScriptName; Functions.HttpProc = HttpProc; Functions.FtpProc = FtpProc; while(1){ ThisThread = GetFreeThread(&HT); FD_ZERO(&acceptfds); for( i=0 ; i < HT.c_servers ; i++ ) FD_SET(HT.server[i].sock,&acceptfds); timeout.tv_sec=60; timeout.tv_usec=0; i = select(FD_SETSIZE,&acceptfds,NULL,NULL,&timeout); for( i=0 ; i < HT.c_servers ; i++ ){ if( FD_ISSET(HT.server[i].sock,&acceptfds) ){ do{ addr_size=sizeof(struct sockaddr); ThisThread->msgsock = accept(HT.server[i].sock, (struct sockaddr *)&(ThisThread->addr), &addr_size); }while( #ifdef WIN32 ThisThread->msgsock == INVALID_SOCKET #else ThisThread->msgsock <= 0 #endif ); thread_LockMutex(&(HT.mxState)); iState = HT.iState; thread_UnlockMutex(&(HT.mxState)); if( iState == STATE_SHUT ){/* we have to stop */ /* wait for all threads to stop */ for( iL = 0 ; iL < HT.lWaitCount ; iL++ ){ thread_LockMutex(&(HT.mxFirstFreeThread)); cThread = HT.cThread; thread_UnlockMutex(&(HT.mxFirstFreeThread)); if( cThread == 1 )break; Sleep(HT.lWaitSec*SLEEPER); } return 0; } ThisThread->SocketOpened = 1; ThisThread->server_index = i; thread_CreateThread(&(ThisThread->T),HitHandler,ThisThread); } } } /* we never get here */ return 0; }