static void a_enterInterruptlevel(void) { /* synchronize Windows threads */ MutexWait(windowsThreadSyncMutex_g); intlevelCounter_g++; /* wait here until it is allowed to run the pico]OS functions */ if (intlevelCounter_g == 1) { again: interruptActive_g = 1; barrier(); while ((blockInterrupt_g != 0) || (taskLockCnt_g != 0)) { interruptWaiting_g = 1; if (taskLockCnt_g == 0) { if (!interruptWaiting_g) SemaWait(interruptWaitSem_g); interruptWaiting_g = 0; break; } interruptActive_g = 0; SemaWait(interruptWaitSem_g); interruptActive_g = 1; } /* assert(taskLockCnt_g == 0); */ SemaWait(globalSyncSem_g); /* assert(taskLockCnt_g == 0); */ if (taskLockCnt_g != 0) { /* this is a fast hack to catch a seldom race condition on Windows 9x machines */ SemaSignal(globalSyncSem_g); fprintf(stderr, "WARNING: arch_c.c: race condition detected\n"); goto again; } interruptExecuting_g = 1; assert(taskLockCnt_g == 0); } }
int SipperMediaListener::startListener(unsigned short port) { #ifndef __UNIX__ WSADATA wsaData; int iResult; iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { logger.logMsg(ERROR_FLAG, 0, "WSAStartup failed: %d\n", iResult); exit(1); } #endif SipperMediaConfig &config = SipperMediaConfig::getInstance(); int inActiveDuration = atoi(config.getConfig("Global", "InActiveDuration", "300").c_str()); if(inActiveDuration < 0) { logger.logMsg(ERROR_FLAG, 0, "InActiveTimer is -ve. Using default Value\n"); inActiveDuration = 300; } _shutdownFlag = false; int sock = socket(AF_INET, SOCK_STREAM, 0); u_int flagOn = 1; #ifndef __UNIX__ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&flagOn, sizeof(flagOn)); #else setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flagOn, sizeof(flagOn)); #endif sockaddr_in svrInfo; memset(&svrInfo, 0, sizeof(sockaddr_in)); svrInfo.sin_family = AF_INET; svrInfo.sin_addr.s_addr = INADDR_ANY; svrInfo.sin_port = htons(port); if(bind(sock, (struct sockaddr *)&svrInfo, sizeof(sockaddr_in)) == -1) { logger.logMsg(ERROR_FLAG, 0, "Unable to bind to Port[%d] Error[%s].\n", port, SipperMediaListener::errorString().c_str()); SipperMediaListener::disconnectSocket(sock); return -1; } if(listen(sock, 5) == -1) { logger.logMsg(ERROR_FLAG, 0, "Listen call failed for Port[%d] Error[%s].\n", port, SipperMediaListener::errorString().c_str()); SipperMediaListener::disconnectSocket(sock); return -2; } SipperMediaListener::setNonBlocking(sock); SipperMediaListener::setTcpNoDelay(sock); fd_set read_fds; while(true) { FD_ZERO(&read_fds); FD_SET(sock, &read_fds); if(inActiveDuration > 0) { MutexGuard(&_mutex); struct timeval currtime; SipperMediaPortable::getTimeOfDay(&currtime); if(currtime.tv_sec > (_lastActivityTime.tv_sec + inActiveDuration)) { if(_controllerMap.size() == 0) { logger.logMsg(ALWAYS_FLAG, 0, "Shutdown on inActivity."); _shutdownFlag = true; break; } } } struct timeval time_out; time_out.tv_sec = 1; time_out.tv_usec = 0; if(select(sock + 1, &read_fds, NULL, NULL, &time_out) == -1) { std::string errMsg = SipperMediaListener::errorString(); logger.logMsg(ERROR_FLAG, 0, "Error getting socket status. [%s]\n", errMsg.c_str()); continue; } if(_shutdownFlag) { break; } if(FD_ISSET(sock, &read_fds)) { struct sockaddr_in cliAddr; memset(&cliAddr, 0, sizeof(cliAddr)); #ifdef __UNIX__ socklen_t len = sizeof(cliAddr); #else int len = sizeof(cliAddr); #endif int accSock = accept(sock, (struct sockaddr *)&cliAddr, &len); if(accSock == -1) { std::string errMsg = SipperMediaListener::errorString(); logger.logMsg(ERROR_FLAG, 0, "Accept failed for [%d]. [%s]\n", sock, errMsg.c_str()); continue; } logger.logMsg(ALWAYS_FLAG, 0, "Accepted connection Sock[%d] From IP[%s] Port[%d]\n", accSock, inet_ntoa(cliAddr.sin_addr), ntohs(cliAddr.sin_port)); SipperMediaListener::setNonBlocking(accSock); SipperMediaListener::setTcpNoDelay(accSock); { MutexGuard(&_mutex); SipperMediaPortable::getTimeOfDay(&_lastActivityTime); } pthread_t currthread; SipperMediaListenerThreadData *thrData = new SipperMediaListenerThreadData; thrData->listener = this; thrData->socket = accSock; pthread_create(&currthread, NULL, SipperMediaListener::_startControllerThread, (void *)thrData); } } SipperMediaListener::disconnectSocket(sock); this->shutdown(); { MutexGuard(&_mutex); while(_controllerMap.size() > 0) { logger.logMsg(ALWAYS_FLAG, 0, "Waiting for [%d] controllers to exit.\n", _controllerMap.size()); MutexWait(1000); } } #ifndef __UNIX__ Sleep(100); #else sleep(1); #endif logger.logMsg(ALWAYS_FLAG, 0, "Listener ended.\n"); return 0; }