Ejemplo n.º 1
0
void NetworkManager::AssignTask(void(*callback)())
{
	int count = GetFreeThread();
	if (count != -1)
	{
		m_ptrThread[count]->SetThreadBusy();
		m_ptrThread[count]->SetFunction(callback);
		m_ptrThread[count]->SignalWorkEvent();
	}
}
Ejemplo n.º 2
0
/*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;
  }