/*! Remove a thread. Return zero if a thread was removed. */ int Server::removeThread (u_long ID) { int ret = 1; string msg ("remove-thread"); vector<Multicast<string, void*, int>*>* handlers; handlers = getHandlers (msg); threadsMutex->lock (); if (handlers) { for (size_t i = 0; i < handlers->size (); i++) { (*handlers)[i]->updateMulticast (this, msg, &ID); } } for (list<ClientsThread*>::iterator it = threads.begin (); it != threads.end (); it++) { if ((*it)->id == ID) { (*it)->stop (); ret = 0; threads.erase (it); break; } } threadsMutex->unlock (); return ret; }
int MessageDispatcher::addHandler(MessageHandler* o){ std::vector<MessageHandler*>& handlers = getHandlers(); if( std::find(handlers.begin(), handlers.end(), o) == handlers.end()){ handlers.push_back(o) ; return handlers.size()-1 ; } return -1; }
/*! Create a new thread. */ int Server::addThread (bool staticThread) { int ret; string msg ("new-thread"); ClientsThread* newThread = 0; vector<Multicast<string, void*, int>*>* handlers; purgeThreadsThreshold = 1; if (isRebooting ()) return -1; if (!staticThread) { bool restored = false; for (list<ClientsThread*>::iterator it = threads.begin (); it != threads.end (); it++) { ClientsThread* thread = *it; if (thread->isToDestroy ()) { thread->setToDestroy (0); restored = true; break; } } if (restored) return 0; } newThread = new ClientsThread (this); handlers = getHandlers (msg); if (handlers) { for (size_t i = 0; i < handlers->size (); i++) { (*handlers)[i]->updateMulticast (this, msg, newThread); } } newThread->setStatic (staticThread); newThread->id = (u_long) (++currentThreadID); ret = newThread->run (); if (ret) { log (MYSERVER_LOG_MSG_ERROR, _("Error creating thread")); return -1; } threads.push_back (newThread); return 0; }
/*! Get notified when a connection is closed. */ int Server::notifyDeleteConnection (ConnectionPtr s) { string msg ("remove-connection"); vector<Multicast<string, void*, int>*>* handlers; handlers = getHandlers (msg); if (handlers) for (size_t i = 0; i < handlers->size (); i++) (*handlers)[i]->updateMulticast (this, msg, s); return 0; }
void EventEmitter_regCore(struct EventEmitter* eventEmitter, struct Iface* iface, enum PFChan_Pathfinder ev) { struct EventEmitter_pvt* ee = Identity_check((struct EventEmitter_pvt*) eventEmitter); iface->connectedIf = &ee->trickIf; struct ArrayList_Ifaces* l = getHandlers(ee, ev, true); if (!l) { Assert_true(ev == 0); return; } ArrayList_Ifaces_add(l, iface); }
static Iface_DEFUN incomingFromPathfinder(struct Message* msg, struct Iface* iface) { struct Pathfinder* pf = Identity_containerOf(iface, struct Pathfinder, iface); struct EventEmitter_pvt* ee = Identity_check((struct EventEmitter_pvt*) pf->ee); if (msg->length < 4) { Log_debug(ee->log, "DROPPF runt"); return NULL; } enum PFChan_Pathfinder ev = Message_pop32(msg, NULL); Message_push32(msg, pf->pathfinderId, NULL); Message_push32(msg, ev, NULL); if (ev <= PFChan_Pathfinder__TOO_LOW || ev >= PFChan_Pathfinder__TOO_HIGH) { Log_debug(ee->log, "DROPPF invalid type [%d]", ev); return NULL; } if (!PFChan_Pathfinder_sizeOk(ev, msg->length)) { Log_debug(ee->log, "DROPPF incorrect length[%d] for type [%d]", msg->length, ev); return NULL; } if (pf->state == Pathfinder_state_DISCONNECTED) { if (ev != PFChan_Pathfinder_CONNECT) { Log_debug(ee->log, "DROPPF disconnected and event != CONNECT event:[%d]", ev); return NULL; } } else if (pf->state != Pathfinder_state_CONNECTED) { Log_debug(ee->log, "DROPPF error state"); return NULL; } if (handleFromPathfinder(ev, msg, ee, pf)) { return NULL; } struct ArrayList_Ifaces* handlers = getHandlers(ee, ev, false); if (!handlers) { return NULL; } for (int i = 0; i < handlers->length; i++) { struct Message* messageClone = Message_clone(msg, msg->alloc); struct Iface* iface = ArrayList_Ifaces_get(handlers, i); // We have to call this manually because we don't have an interface handy which is // actually plumbed with this one. Assert_true(iface); Assert_true(iface->send); Iface_CALL(iface->send, messageClone, iface); } return NULL; }
/*! Reboot the server. Returns non zero on errors. */ int Server::reboot () { int ret; string msg ("reboot-server"); vector<Multicast<string, void*, int>*>* handlers; handlers = getHandlers (msg); if (handlers) { for (size_t i = 0; i < handlers->size (); i++) (*handlers)[i]->updateMulticast (this, msg, 0); } serverReady = false; /* Reset the toReboot flag. */ toReboot = false; rebooting = true; /* Do nothing if the reboot is disabled. */ if (!autoRebootEnabled) return 0; /* Do a beep if outputting to console. */ if (logLocation.find ("console://") != string::npos) { char beep[] = { static_cast<char>(0x7), '\0' }; string beepStr (beep); logManager->log (this, "MAINLOG", logLocation, beepStr); } log (MYSERVER_LOG_MSG_INFO, _("Rebooting")); if (mustEndServer) return 0; mustEndServer = true; ret = terminate (); if (ret) return ret; mustEndServer = false; rebooting = false; ret = initialize () || postLoad (); if (ret) { log (MYSERVER_LOG_MSG_INFO, _("The server could not be restarted")); return ret; } serverReady = true; log (MYSERVER_LOG_MSG_INFO, _("Restarted")); return 0; }
/*! Add a new connection. A connection is defined using a connection struct. */ ConnectionPtr Server::addConnectionToList (Socket* s, MYSERVER_SOCKADDRIN* /*asockIn*/, char *ipAddr, char *localIpAddr, u_short port, u_short localPort, int /*id*/) { int doSSLhandshake = 0; int doFastCheck = 0; Protocol* protocol; int opts = 0; ConnectionPtr newConnection; vector<Multicast<string, void*, int>*>* handlers; connectionsPoolLock.lock (); try { newConnection = connectionsPool.forcedGet (); connectionsPoolLock.unlock (); } catch (...) { connectionsPoolLock.unlock (); throw; } if (!newConnection) return NULL; else newConnection->init (); newConnection->setPort (port); newConnection->setTimeout ( getTicks () ); newConnection->setLocalPort (localPort); newConnection->setIpAddr (ipAddr); newConnection->setLocalIpAddr (localIpAddr); newConnection->host = vhostManager.getVHost (0, localIpAddr, localPort); if (newConnection->host == NULL) { try { connectionsPoolLock.lock (); connectionsPool.put (newConnection); connectionsPoolLock.unlock (); } catch (...) { connectionsPoolLock.unlock (); throw; } return 0; } protocol = getProtocol (newConnection->host->getProtocolName ()); if (protocol) opts = protocol->getProtocolOptions (); if (opts & Protocol::SSL) doSSLhandshake = 1; if (opts & Protocol::FAST_CHECK) doFastCheck = 1; string msg ("new-connection"); handlers = getHandlers (msg); if (handlers) { for (size_t i = 0; i < handlers->size (); i++) if ((*handlers)[i]->updateMulticast (this, msg, newConnection) == 1) { connectionsPoolLock.lock (); try { connectionsPool.put (newConnection); connectionsPoolLock.unlock (); } catch (...) { connectionsPoolLock.unlock (); throw; } return 0; } } /* Do the SSL handshake if required. */ if (doSSLhandshake) { int ret = 0; SslSocket *sslSocket = new SslSocket (s); sslSocket->setSSLContext (newConnection->host->getSSLContext (), newConnection->host->getSSLPriorityCache ()); ret = sslSocket->sslAccept (); if (ret < 0) { connectionsPoolLock.lock (); try { connectionsPool.put (newConnection); connectionsPoolLock.unlock (); } catch (...) { connectionsPoolLock.unlock (); throw; } delete sslSocket; return 0; } newConnection->socket = sslSocket; } else newConnection->socket = s; if (doFastCheck) { newConnection->setScheduled (1); newConnection->setForceControl (1); newConnection->socket->setNonBlocking (1); connectionsScheduler.addNewReadyConnection (newConnection); } else connectionsScheduler.addNewWaitingConnection (newConnection); /* If defined maxConnections and the number of active connections is bigger than it say to the protocol that will parse the connection to remove it from the active connections list. */ if (maxConnections && connectionsScheduler.getNumAliveConnections () > maxConnections) newConnection->setToRemove (Connection::REMOVE_OVERLOAD); connectionsScheduler.registerConnectionID (newConnection); return newConnection; }
void MessageDispatcher::process(sofa::helper::logging::Message& m){ std::vector<MessageHandler*>& handlers = getHandlers(); for( size_t i=0 ; i<handlers.size() ; i++ ) handlers[i]->process(m) ; }
void MessageDispatcher::clearHandlers(){ std::vector<MessageHandler*>& handlers = getHandlers(); handlers.clear() ; }
int MessageDispatcher::rmHandler(MessageHandler* o){ std::vector<MessageHandler*>& handlers = getHandlers(); handlers.erase(remove(handlers.begin(), handlers.end(), o), handlers.end()); return handlers.size()-1 ; }