void Scheduler::schedulerThread(void* p) { Scheduler* scheduler = (Scheduler*)p; #if defined __EXCEPTION_TRACER__ ExceptionHandler schedulerExceptionHandler; schedulerExceptionHandler.InstallHandler(); #endif srand((uint32_t)OTSYS_TIME()); boost::unique_lock<boost::mutex> eventLockUnique(scheduler->m_eventLock, boost::defer_lock); while(Scheduler::m_threadState != Scheduler::STATE_TERMINATED) { SchedulerTask* task = NULL; bool run = false, ret = false; // check if there are events waiting... eventLockUnique.lock(); if(scheduler->m_eventList.empty()) // unlock mutex and wait for signal scheduler->m_eventSignal.wait(eventLockUnique); else // unlock mutex and wait for signal or timeout ret = scheduler->m_eventSignal.timed_wait(eventLockUnique, scheduler->m_eventList.top()->getCycle()); // the mutex is locked again now... if(!ret && Scheduler::m_threadState != Scheduler::STATE_TERMINATED) { // ok we had a timeout, so there has to be an event we have to execute... task = scheduler->m_eventList.top(); scheduler->m_eventList.pop(); // check if the event was stopped EventIds::iterator it = scheduler->m_eventIds.find(task->getEventId()); if(it != scheduler->m_eventIds.end()) { // was not stopped so we should run it run = true; scheduler->m_eventIds.erase(it); } } eventLockUnique.unlock(); // add task to dispatcher if(task) { // if it was not stopped if(run) { task->unsetExpiration(); Dispatcher::getInstance().addTask(task); } else delete task; // was stopped, have to be deleted here } } #if defined __EXCEPTION_TRACER__ schedulerExceptionHandler.RemoveHandler(); #endif }
int main(int argc, char* argv[]) { StringVec args = StringVec(argv, argv + argc); if(argc > 1 && !argumentsHandler(args)) return 0; std::set_new_handler(allocationHandler); ServiceManager servicer; g_config.startup(); #ifdef __OTSERV_ALLOCATOR_STATS__ boost::thread(boost::bind(&allocatorStatsThread, (void*)NULL)); // TODO: shutdown this thread? #endif #ifdef __EXCEPTION_TRACER__ ExceptionHandler mainExceptionHandler; mainExceptionHandler.InstallHandler(); #endif #ifndef WINDOWS // ignore sigpipe... struct sigaction sigh; sigh.sa_handler = SIG_IGN; sigh.sa_flags = 0; sigemptyset(&sigh.sa_mask); sigaction(SIGPIPE, &sigh, NULL); // register signals signal(SIGHUP, signalHandler); //save signal(SIGTRAP, signalHandler); //clean signal(SIGCHLD, signalHandler); //refresh signal(SIGUSR1, signalHandler); //close server signal(SIGUSR2, signalHandler); //open server signal(SIGCONT, signalHandler); //reload all signal(SIGQUIT, signalHandler); //save & shutdown signal(SIGTERM, signalHandler); //shutdown #endif OutputHandler::getInstance(); Dispatcher::getInstance().addTask(createTask(boost::bind(otserv, args, &servicer))); g_loaderSignal.wait(g_loaderUniqueLock); if(servicer.isRunning()) { std::clog << ">> " << g_config.getString(ConfigManager::SERVER_NAME) << " server Online!" << std::endl << std::endl; servicer.run(); } else std::clog << ">> " << g_config.getString(ConfigManager::SERVER_NAME) << " server Offline! No services available..." << std::endl << std::endl; #ifdef __EXCEPTION_TRACER__ mainExceptionHandler.RemoveHandler(); #endif return 0; }
OTSYS_THREAD_RETURN Dispatcher::dispatcherThread(void* p) { #if defined __EXCEPTION_TRACER__ ExceptionHandler dispatcherExceptionHandler; dispatcherExceptionHandler.InstallHandler(); #endif srand((uint32_t)OTSYS_TIME()); OutputMessagePool* outputPool = NULL; while(Dispatcher::m_threadState != Dispatcher::STATE_TERMINATED) { Task* task = NULL; // check if there are tasks waiting OTSYS_THREAD_LOCK(getDispatcher().m_taskLock, ""); if(getDispatcher().m_taskList.empty()) //if the list is empty wait for signal OTSYS_THREAD_WAITSIGNAL(getDispatcher().m_taskSignal, getDispatcher().m_taskLock); if(!getDispatcher().m_taskList.empty() && Dispatcher::m_threadState != Dispatcher::STATE_TERMINATED) { // take the first task task = getDispatcher().m_taskList.front(); getDispatcher().m_taskList.pop_front(); } OTSYS_THREAD_UNLOCK(getDispatcher().m_taskLock, ""); // finally execute the task... if(!task) continue; if(!task->hasExpired()) { if((outputPool = OutputMessagePool::getInstance())) outputPool->startExecutionFrame(); (*task)(); if(outputPool) outputPool->sendAll(); g_game.clearSpectatorCache(); } delete task; } #if defined __EXCEPTION_TRACER__ dispatcherExceptionHandler.RemoveHandler(); #endif #if not defined(WIN32) return NULL; #endif }
void Dispatcher::dispatcherThread(void* p) { Dispatcher* dispatcher = (Dispatcher*)p; #if defined __EXCEPTION_TRACER__ ExceptionHandler dispatcherExceptionHandler; dispatcherExceptionHandler.InstallHandler(); #endif srand((uint32_t)OTSYS_TIME()); OutputMessagePool* outputPool = NULL; boost::unique_lock<boost::mutex> taskLockUnique(dispatcher->m_taskLock, boost::defer_lock); while(Dispatcher::m_threadState != Dispatcher::STATE_TERMINATED) { Task* task = NULL; // check if there are tasks waiting taskLockUnique.lock(); if(dispatcher->m_taskList.empty()) //if the list is empty wait for signal dispatcher->m_taskSignal.wait(taskLockUnique); if(!dispatcher->m_taskList.empty() && Dispatcher::m_threadState != Dispatcher::STATE_TERMINATED) { // take the first task task = dispatcher->m_taskList.front(); dispatcher->m_taskList.pop_front(); } taskLockUnique.unlock(); // finally execute the task... if(!task) continue; if(!task->hasExpired()) { if((outputPool = OutputMessagePool::getInstance())) outputPool->startExecutionFrame(); (*task)(); if(outputPool) outputPool->sendAll(); g_game.clearSpectatorCache(); } delete task; } #if defined __EXCEPTION_TRACER__ dispatcherExceptionHandler.RemoveHandler(); #endif }
__declspec(dllexport) DWORD Start(void* context) { // Because the remote DLL injector does not call DllMain, we have to // initialize the CRT manually _CRT_INIT(NULL, DLL_PROCESS_ATTACH, NULL); HANDLE hCrashPipe = reinterpret_cast<HANDLE>(context); ExceptionHandler* e = new (std::nothrow) ExceptionHandler(wstring(), NULL, NULL, NULL, ExceptionHandler::HANDLER_ALL, MiniDumpNormal, hCrashPipe, NULL); if (e) e->set_handle_debug_exceptions(true); return 1; }
OTSYS_THREAD_RETURN Dispatcher::dispatcherThread(void* p) { #if defined __EXCEPTION_TRACER__ ExceptionHandler dispatcherExceptionHandler; dispatcherExceptionHandler.InstallHandler(); #endif srand((unsigned int)OTSYS_TIME()); while(!Dispatcher::m_shutdown){ Task* task = NULL; // check if there are tasks waiting OTSYS_THREAD_LOCK(getDispatcher().m_taskLock, "") if(getDispatcher().m_taskList.empty()){ //if the list is empty wait for signal OTSYS_THREAD_WAITSIGNAL(getDispatcher().m_taskSignal, getDispatcher().m_taskLock); } if(!getDispatcher().m_taskList.empty() && !Dispatcher::m_shutdown){ // take the first task task = getDispatcher().m_taskList.front(); getDispatcher().m_taskList.pop_front(); } OTSYS_THREAD_UNLOCK(getDispatcher().m_taskLock, ""); // finally execute the task... if(task){ OutputMessagePool::getInstance()->startExecutionFrame(); (*task)(); delete task; OutputMessagePool::getInstance()->sendAll(); g_game.clearSpectatorCache(); } } #if defined __EXCEPTION_TRACER__ dispatcherExceptionHandler.RemoveHandler(); #endif #if defined WIN32 || defined __WINDOWS__ // #else return 0; #endif }
void Dispatcher::dispatcherThread(void* p) { #if defined __EXCEPTION_TRACER__ ExceptionHandler dispatcherExceptionHandler; dispatcherExceptionHandler.InstallHandler(); #endif srand((unsigned int)OTSYS_TIME()); #ifdef __DEBUG_SCHEDULER__ std::cout << "Starting Dispatcher" << std::endl; #endif OutputMessagePool* outputPool; // NOTE: second argument defer_lock is to prevent from immediate locking boost::unique_lock<boost::mutex> taskLockUnique(getDispatcher().m_taskLock, boost::defer_lock); while(Dispatcher::m_threadState != Dispatcher::STATE_TERMINATED){ Task* task = NULL; // check if there are tasks waiting taskLockUnique.lock();//getDispatcher().m_taskLock.lock(); if(getDispatcher().m_taskList.empty()){ //if the list is empty wait for signal #ifdef __DEBUG_SCHEDULER__ std::cout << "Dispatcher: Waiting for task" << std::endl; #endif getDispatcher().m_taskSignal.wait(taskLockUnique); } #ifdef __DEBUG_SCHEDULER__ std::cout << "Dispatcher: Signalled" << std::endl; #endif if(!getDispatcher().m_taskList.empty() && (Dispatcher::m_threadState != Dispatcher::STATE_TERMINATED)){ // take the first task task = getDispatcher().m_taskList.front(); getDispatcher().m_taskList.pop_front(); } taskLockUnique.unlock(); // finally execute the task... if(task){ OutputMessagePool::getInstance()->startExecutionFrame(); (*task)(); delete task; outputPool = OutputMessagePool::getInstance(); if(outputPool){ outputPool->sendAll(); } g_game.clearSpectatorCache(); #ifdef __DEBUG_SCHEDULER__ std::cout << "Dispatcher: Executing task" << std::endl; #endif } } #if defined __EXCEPTION_TRACER__ dispatcherExceptionHandler.RemoveHandler(); #endif }
int main(int argc, char *argv[]) { std::srand((uint32_t)OTSYS_TIME()); StringVec args = StringVec(argv, argv + argc); if(argc > 1 && !argumentsHandler(args)) return 0; #else void serverMain(void* param) { std::cout.rdbuf(&g_logger); std::cerr.rdbuf(&g_logger); std::clog.rdbuf(&g_logger); #endif std::set_new_handler(allocationHandler); ServiceManager servicer; g_config.startup(); #ifdef __OTSERV_ALLOCATOR_STATS__ //boost::thread(boost::bind(&allocatorStatsThread, (void*)NULL)); // TODO: this thread needs a shutdown (timed_lock + interrupt? .interrupt + .unlock) #endif #ifdef __EXCEPTION_TRACER__ ExceptionHandler mainExceptionHandler; mainExceptionHandler.InstallHandler(); #endif #ifndef WINDOWS // ignore sigpipe... struct sigaction sigh; sigh.sa_handler = SIG_IGN; sigh.sa_flags = 0; sigemptyset(&sigh.sa_mask); sigaction(SIGPIPE, &sigh, NULL); // register signals signal(SIGHUP, signalHandler); //save signal(SIGTRAP, signalHandler); //clean signal(SIGCHLD, signalHandler); //refresh signal(SIGUSR1, signalHandler); //close server signal(SIGUSR2, signalHandler); //open server signal(SIGCONT, signalHandler); //reload all signal(SIGQUIT, signalHandler); //save & shutdown signal(SIGTERM, signalHandler); //shutdown #endif Dispatcher::getInstance().addTask(createTask(boost::bind(otserv, #if !defined(WINDOWS) || defined(_CONSOLE) args, #endif &servicer))); g_loaderSignal.wait(g_loaderUniqueLock); boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); if(servicer.isRunning()) { Status::getInstance(); std::clog << ">> " << g_config.getString(ConfigManager::SERVER_NAME) << " server Online!" << std::endl << std::endl; #if defined(WINDOWS) && !defined(_CONSOLE) SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> server Online!"); GUI::getInstance()->m_connections = true; #endif servicer.run(); } else { Status::getInstance(); std::clog << ">> " << g_config.getString(ConfigManager::SERVER_NAME) << " server Offline! No services available..." << std::endl << std::endl; #if defined(WINDOWS) && !defined(_CONSOLE) SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> server Offline! No services available..."); GUI::getInstance()->m_connections = true; #endif } Dispatcher::getInstance().exit(); Scheduler::getInstance().exit(); #ifdef __EXCEPTION_TRACER__ mainExceptionHandler.RemoveHandler(); #endif #if !defined(WINDOWS) || defined(_CONSOLE) return 0; #endif }
void Scheduler::schedulerThread(void* p) { Scheduler* scheduler=(Scheduler*)p; #ifdef __EXCEPTION_TRACER__ ExceptionHandler schedulerExceptionHandler; schedulerExceptionHandler.InstallHandler(); #endif #ifdef __DEBUG_SCHEDULER__ std::cout << "Starting Scheduler" << std::endl; #endif // NOTE: second argument defer_lock is to prevent from immediate locking boost::unique_lock<boost::mutex> eventLockUnique(scheduler->m_eventLock, boost::defer_lock); while (scheduler->m_threadState!=STATE_TERMINATED) { SchedulerTask* task=nullptr; bool runTask=false; bool ret=true; // check if there are events waiting... eventLockUnique.lock(); if (scheduler->m_eventList.empty()) { #ifdef __DEBUG_SCHEDULER__ std::cout << "Scheduler: No events" << std::endl; #endif scheduler->m_eventSignal.wait(eventLockUnique); } else { #ifdef __DEBUG_SCHEDULER__ std::cout << "Scheduler: Waiting for event" << std::endl; #endif ret=scheduler->m_eventSignal.timed_wait(eventLockUnique, scheduler->m_eventList.top()->getCycle()); } #ifdef __DEBUG_SCHEDULER__ std::cout << "Scheduler: Signaled" << std::endl; #endif // the mutex is locked again now... if (ret==false && (scheduler->m_threadState!=STATE_TERMINATED)) { // ok we had a timeout, so there has to be an event we have to execute... task=scheduler->m_eventList.top(); scheduler->m_eventList.pop(); // check if the event was stopped EventIdSet::iterator it=scheduler->m_eventIds.find(task->getEventId()); if (it!=scheduler->m_eventIds.end()) { // was not stopped so we should run it runTask=true; scheduler->m_eventIds.erase(it); } } eventLockUnique.unlock(); // add task to dispatcher if (task) { // if it was not stopped if (runTask) { // Expiration has another meaning for dispatcher tasks, reset it task->setDontExpire(); #ifdef __DEBUG_SCHEDULER__ std::cout << "Scheduler: Executing event " << task->getEventId() << std::endl; #endif g_dispatcher.addTask(task); } else { // was stopped, have to be deleted here delete task; } } } #ifdef __EXCEPTION_TRACER__ schedulerExceptionHandler.RemoveHandler(); #endif }
int main(int argc, char *argv[]) { StringVec args = StringVec(argv, argv + argc); if(argc > 1 && !argumentsHandler(args)) return 0; #else void serverMain(void* param) { std::cout.rdbuf(&g_logger); std::cerr.rdbuf(&g_logger); #endif std::set_new_handler(allocationHandler); ServiceManager servicer; g_config.startup(); #ifdef __OTSERV_ALLOCATOR_STATS__ boost::thread(boost::bind(&allocatorStatsThread, (void*)NULL)); // TODO: destruct this thread... #endif #ifdef __EXCEPTION_TRACER__ ExceptionHandler mainExceptionHandler; mainExceptionHandler.InstallHandler(); #endif #ifndef WINDOWS // ignore sigpipe... struct sigaction sigh; sigh.sa_handler = SIG_IGN; sigh.sa_flags = 0; sigemptyset(&sigh.sa_mask); sigaction(SIGPIPE, &sigh, NULL); // register signals signal(SIGHUP, signalHandler); //save signal(SIGTRAP, signalHandler); //clean signal(SIGCHLD, signalHandler); //refresh signal(SIGUSR1, signalHandler); //close server signal(SIGUSR2, signalHandler); //open server signal(SIGCONT, signalHandler); //reload all signal(SIGQUIT, signalHandler); //save & shutdown signal(SIGTERM, signalHandler); //shutdown #endif Dispatcher::getInstance().addTask(createTask(boost::bind(otserv, #if !defined(WINDOWS) || defined(__CONSOLE__) args, #endif &servicer))); g_loaderSignal.wait(g_loaderUniqueLock); #if !defined(WINDOWS) || defined(__CONSOLE__) std::string outPath = g_config.getString(ConfigManager::OUT_LOG), errPath = g_config.getString(ConfigManager::ERROR_LOG); if(outPath.length() < 3) outPath = ""; else if(outPath[0] != '/' && outPath[1] != ':') { outPath = getFilePath(FILE_TYPE_LOG, outPath); std::cout << "> Logging output to file: " << outPath << std::endl; } if(errPath.length() < 3) errPath = ""; else if(errPath[0] != '/' && errPath[1] != ':') { errPath = getFilePath(FILE_TYPE_LOG, errPath); std::cout << "> Logging errors to file: " << errPath << std::endl; } if(outPath != "") { boost::shared_ptr<std::ofstream> outFile; outFile.reset(new std::ofstream(outPath.c_str(), (g_config.getBool(ConfigManager::TRUNCATE_LOGS) ? std::ios::trunc : std::ios::app) | std::ios::out)); if(!outFile->is_open()) startupErrorMessage("Could not open output log file for writing!"); std::cout.rdbuf(outFile->rdbuf()); } if(errPath != "") { boost::shared_ptr<std::ofstream> errFile; errFile.reset(new std::ofstream(errPath.c_str(), (g_config.getBool(ConfigManager::TRUNCATE_LOGS) ? std::ios::trunc : std::ios::app) | std::ios::out)); if(!errFile->is_open()) startupErrorMessage("Could not open error log file for writing!"); std::cerr.rdbuf(errFile->rdbuf()); } #endif if(servicer.isRunning()) { std::cout << ">> " << g_config.getString(ConfigManager::SERVER_NAME) << " server Online!" << std::endl << std::endl; #if defined(WINDOWS) && !defined(__CONSOLE__) SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> Status: Online!"); GUI::getInstance()->m_connections = true; #endif servicer.run(); } else { std::cout << ">> " << g_config.getString(ConfigManager::SERVER_NAME) << " server Offline! No services available..." << std::endl << std::endl; #if defined(WINDOWS) && !defined(__CONSOLE__) SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> Status: Offline!"); GUI::getInstance()->m_connections = true; #endif } #ifdef __EXCEPTION_TRACER__ mainExceptionHandler.RemoveHandler(); #endif #if !defined(WINDOWS) || defined(__CONSOLE__) return 0; #endif }
void Dispatcher::dispatcherThread(void* p) { Dispatcher* dispatcher = static_cast<Dispatcher*>(p); ExceptionHandler dispatcherExceptionHandler; dispatcherExceptionHandler.InstallHandler(); #ifdef __DEBUG_SCHEDULER__ std::cout << "Starting Dispatcher" << std::endl; #endif OutputMessagePool* outputPool; // NOTE: second argument defer_lock is to prevent from immediate locking boost::unique_lock<boost::mutex> taskLockUnique(dispatcher->m_taskLock, boost::defer_lock); while (dispatcher->m_threadState != STATE_TERMINATED) { Task* task = NULL; // check if there are tasks waiting taskLockUnique.lock(); if (dispatcher->m_taskList.empty()) { //if the list is empty wait for signal #ifdef __DEBUG_SCHEDULER__ std::cout << "Dispatcher: Waiting for task" << std::endl; #endif dispatcher->m_taskSignal.wait(taskLockUnique); } #ifdef __DEBUG_SCHEDULER__ std::cout << "Dispatcher: Signalled" << std::endl; #endif if (!dispatcher->m_taskList.empty() && (dispatcher->m_threadState != STATE_TERMINATED)) { // take the first task task = dispatcher->m_taskList.front(); dispatcher->m_taskList.pop_front(); } taskLockUnique.unlock(); // finally execute the task... if (task) { if (!task->hasExpired()) { OutputMessagePool::getInstance()->startExecutionFrame(); (*task)(); outputPool = OutputMessagePool::getInstance(); if (outputPool) { outputPool->sendAll(); } g_game.clearSpectatorCache(); } delete task; #ifdef __DEBUG_SCHEDULER__ std::cout << "Dispatcher: Executing task" << std::endl; #endif } } dispatcherExceptionHandler.RemoveHandler(); }