int main (int argc, char* argv[]) { // We get the number of cores to be used. If we don't give any number, // we set to 0 which implies the usage of all available cores size_t nbCores = (argc >=2 ? atoi(argv[1]) : 0); // We create an iterator over an integer range int nmax = 1000; Range<int>::Iterator it (1,nmax); // We open a file. This will be our shared resource between threads. fstream file ("out", std::fstream::out); // For our file, we can't use intrinsics like we did for integer addition, // so we need a general synchronization mechanism that will be shared by the threads. ISynchronizer* synchro = System::thread().newSynchronizer(); // We create a dispatcher configured for 'nbCores' cores. Dispatcher dispatcher (nbCores, 1); // We iterate the range. NOTE: we could also use lambda expression (easing the code readability) dispatcher.iterate (it, Functor(synchro,file)); // We close the file file.close(); // We get rid of the synchronizer delete synchro; }
/*=====================================================================*/ void GData::set_partition(GPartitioner *P) { partitioner = P; assert(P); child_cnt = P->y * P->x; children = new GData*[child_cnt]; assert(P->y); assert(P->x); int m = M/P->y; int n = N/P->x; for(int i=0; i<child_cnt; i++) { int px = i/P->y; int py = i%P->y; ostringstream os; os << name << "_" << setw(2) << setfill('0') << py << "_" << setw(2) << setfill('0') << px; string ch_name = os.str(); LOG_INFO(LOG_MLEVEL,"Child data :%s of %dx%d at blk(%d,%d) is being created.\n",ch_name.c_str(),m,n,py,px); children[i] = new GData(m,n,ch_name,this,i); } Dispatcher *dis = get_dispatcher(); if ( dis != nullptr) dis->data_partitioned(this); GPartitioner *next_p=partitioner->get_next(); if ( next_p != nullptr) for(int i=0; i<child_cnt; i++) { LOG_INFO(LOG_MLEVEL,"Cascade partition to %s with %dx%d\n",children[i]->get_name().c_str(),next_p->y,next_p->x); children[i]->set_partition(next_p); } }
void SRC_counter::parse_query_sequences (){ std::string bank_filename = getInput()->getStr(STR_URI_BANK_INPUT).substr(getInput()->getStr(STR_URI_BANK_INPUT).find_last_of("/\\") + 1); BankAlbum banks (getInput()->getStr(STR_URI_QUERY_INPUT)); const std::vector<IBank*>& banks_of_queries = banks.getBanks(); const int number_of_read_sets = banks_of_queries.size(); FILE * pFile; pFile = fopen (getInput()->getStr(STR_OUT_FILE).c_str(), "wb"); cout<<"Query "<<kmer_size<<"-mers from "<<getInput()->getStr(STR_URI_QUERY_INPUT)<<endl; for( int bank_id=0;bank_id<number_of_read_sets;bank_id++){ // iterate each bank IBank* bank=banks_of_queries[bank_id]; LOCAL (bank); // BooleanVector bv; // unsigned long bank_size = get_bank_nb_items(bank); // bv.init_false(bank_size); // quick and dirty. Todo: implement a realocation of the bv in case the estimation is too low. // bv.set_comment(string("Reads from "+bank->getId()+" in "+getInput()->getStr(STR_URI_BANK_INPUT)+" with threshold "+to_string(threshold))); string message("#query_read_id (from bank "+bank->getId()+") mean median min max percentage_shared_positions -- number of shared "+to_string(kmer_size)+"mers with banq "+getInput()->getStr(STR_URI_BANK_INPUT)+"\n"); fwrite((message).c_str(), sizeof(char), message.size(), pFile); string progressMessage("Querying read set "+bank->getId()); ProgressIterator<Sequence> itSeq (*bank, progressMessage.c_str()); ISynchronizer* synchro = System::thread().newSynchronizer(); Dispatcher dispatcher (nbCores, 10000); dispatcher.iterate (itSeq, FunctorQuery(synchro,pFile, kmer_size,&quasiDico, keep_low_complexity, threshold, windows_size));//, &bv)); delete synchro; std::string query_filename = bank->getId().substr(bank->getId().find_last_of("/\\") + 1); // cout<<bv.nb_one()<<" reads in out_"+query_filename+"_in_"+bank_filename+".bv"<<endl; // bv.print("out_"+query_filename+"_in_"+bank_filename+".bv"); } fclose (pFile); }
int close(){ disp.unregisterHandler((Event::EventType)QueueEvents::EMPTY,this); disp.unregisterHandler((Event::EventType)QueueEvents::FULL,this); disp.unregisterHandler((Event::EventType)QueueEvents::NEW_VALUE,this); disp.unregisterHandler((Event::EventType)QueueEvents::END,this); return 0; }
// millisecs std::error_code PollPoller::poll(int timeout, std::unordered_map<int, Dispatcher *> &active_dispatchers) { if (fds_.size() == 0) { ::Sleep(timeout); return LS_OK_ERROR(); } int num_events = ::WSAPoll(&*fds_.begin(), fds_.size(), timeout); if (num_events < 0) { if (SOCK_ERRNO() == CERR(EINTR)) { return LS_OK_ERROR(); } } else if (num_events == 0) { return LS_OK_ERROR(); } else { for (auto it = fds_.begin(); it != fds_.end() && num_events > 0; ++it) { if (it->revents > 0) { --num_events; Dispatcher *dispatcher = dispatchers_[it->fd]; dispatcher->set_poll_event_data( it->revents & (POLLIN | POLLPRI), it->revents & POLLOUT, it->revents & POLLERR, (it->revents & POLLHUP) && !(it->revents & POLLIN)); active_dispatchers[dispatcher->get_fd()] = dispatcher; } } } return LS_OK_ERROR(); }
int main(int argc, char *argv[]) { SetProgramName(argv[0]); MessageServer server("127.0.0.1", 21118); Dispatcher dispatcher; dispatcher.Start(); server.set_dispatcher(&dispatcher); EchoServerMessageHandlerFactory factory; server.set_message_handler_factory(&factory); server.Start(); sigset_t new_mask; sigfillset(&new_mask); sigset_t old_mask; sigset_t wait_mask; sigemptyset(&wait_mask); sigaddset(&wait_mask, SIGINT); sigaddset(&wait_mask, SIGQUIT); sigaddset(&wait_mask, SIGTERM); pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); pthread_sigmask(SIG_SETMASK, &old_mask, 0); pthread_sigmask(SIG_BLOCK, &wait_mask, 0); int sig = 0; sigwait(&wait_mask, &sig); return 0; }
TEST(ContextGroupTests, ConnectionWriteIsThrowingWhenCurrentContextIsInterrupted) { Dispatcher dispatcher; bool interrupted = false; { Event connected(dispatcher); ContextGroup cg1(dispatcher); cg1.spawn([&] { try { auto conn = TcpListener(dispatcher, Ipv4Address("0.0.0.0"), 12345).accept(); conn.write(nullptr, 0); } catch (InterruptedException&) { } }); cg1.spawn([&] { try { auto conn = TcpConnector(dispatcher).connect(Ipv4Address("127.0.0.1"), 12345); connected.set(); dispatcher.yield(); conn.write(nullptr, 0); } catch (InterruptedException&) { interrupted = true; } }); connected.wait(); } ASSERT_TRUE(interrupted); }
TEST(ContextGroupTests, ConnectionReadIsContextIntrerruptible) { Dispatcher dispatcher; bool interrupted = false; { Event connected(dispatcher); ContextGroup cg1(dispatcher); cg1.spawn([&] { try { auto conn = TcpListener(dispatcher, Ipv4Address("0.0.0.0"), 12345).accept(); Timer(dispatcher).sleep(std::chrono::milliseconds(1000)); conn.write(nullptr, 0); } catch (InterruptedException&) { } }); cg1.spawn([&] { try { auto conn = TcpConnector(dispatcher).connect(Ipv4Address("127.0.0.1"), 12345); connected.set(); uint8_t a[10]; conn.read(a, 10); conn.write(nullptr, 0); } catch (InterruptedException&) { interrupted = true; } }); connected.wait(); dispatcher.yield(); } ASSERT_TRUE(interrupted); }
void shouldBeAbleToGetErrorMessageWithRequest() { Dispatcher dispatcher; dispatcher.registerClass("class1", new ErrorMessageHandler()); QCOMPARE(dispatcher.handleRequest("class1/click/button1"), QString("Unable to find top level object \"button1\"")); }
TEST(ContextGroupTests, ContextGroupIsWaitingNestedSpawnsEvenThoughItWasInterrupted) { Dispatcher dispatcher; bool contextFinished = false; bool nestedContextFinished = false; { ContextGroup cg1(dispatcher); cg1.spawn([&] { try { Timer(dispatcher).sleep(std::chrono::milliseconds(100)); contextFinished = true; } catch (InterruptedException&) { cg1.spawn([&] { try { Timer(dispatcher).sleep(std::chrono::milliseconds(100)); nestedContextFinished = true; } catch (InterruptedException&) { } }); } }); dispatcher.yield(); } ASSERT_FALSE(contextFinished); ASSERT_TRUE(nestedContextFinished); }
int main() { Dispatcher disp; Stub<Broker> broker("broker", "unix:the_broker"); disp.addClient(broker); if (broker.connect()) { std::vector<ServiceInfo> services; if (disp.waitForResponse(broker.listServices(), services)) { std::cout << "Available services: " << std::endl; std::for_each(services.begin(), services.end(), printServiceInfo); std::cout << std::endl; std::vector<std::string> waiters; if (disp.waitForResponse(broker.listWaiters(), waiters)) { std::cout << "Waiters waiting for: " << std::endl; std::for_each(waiters.begin(), waiters.end(), printWaiterInfo); std::cout << std::endl; return EXIT_SUCCESS; } } } return EXIT_FAILURE; }
void Subscribe(Receiver<Type>& receiver) { // Check if we already have this event type declared. auto it = m_dispatchers.find(typeid(Type)); if(it == m_dispatchers.end()) { // Create a dispatcher for this event type. auto dispatcher = std::make_unique<Dispatcher<Type>>(); // Add dispatcher to the list. auto pair = DispatcherPair(typeid(Type), std::move(dispatcher)); auto result = m_dispatchers.insert(std::move(pair)); assert(result.second == true); assert(result.first != m_dispatchers.end()); // Set iterator to the newly inserted element. it = result.first; } // Cast the pointer that we already know is a dispatcher. Dispatcher<Type>* dispatcher = reinterpret_cast<Dispatcher<Type>*>(it->second.get()); // Subscribe receiver to the dispatcher. dispatcher->Subscribe(receiver); }
int main (int argc, char* argv[]) { // We get the number of cores to be used. If we don't give any number, // we set to 0 which implies the usage of all available cores size_t nbCores = (argc >=2 ? atoi(argv[1]) : 0); // We create an iterator over an integer range Range<int>::Iterator it (1,20); // We create a dispatcher configured for 'nbCores' cores. Dispatcher dispatcher (nbCores); // We dispatch the range iteration with the dispatcher. // This will create nbCores threads and each thread will be fed with // one value of the defined range // NOTE: we could also use lambda expression (easing the code readability) // Note: third argument is set to groupSize of 1 instead of 1000 (default), // to avoid that 1000 tasks are batched in the same thread. // In practice, when iterating over a large set of elements, set a reasonable // groupSize value, because a groupSize=1 will incur significant overhead // if Functor() is a very quick task. IDispatcher::Status status = dispatcher.iterate (it, Functor(), 1); // We dump some information about the dispatching cout << "nbCores=" << status.nbCores << " time=" << status.time << endl; // IMPORTANT: usage of Dispatcher has sense only if the iterated items // can be processed independently from each other. // The point to understand with the Dispatcher is that it can // iterate any instance of Iterator class. If you have any set of items // that can be enumerated through an Iterator implementation, then you // can parallelize the iteration with a Dispatcher instance }
int main() { producer(); //auto thrp = std::thread(producer); q.Stop(false); q.WaitUntilFinish(); }
void shouldBeAbleToUnregisterAClass() { Dispatcher dispatcher; dispatcher.registerClass("class1", new ReturnNameHandler("class1")); dispatcher.unRegisterClass("class1"); QCOMPARE(dispatcher.handleRequest("class1/click/button1"), QString("")); }
S2::S2(Context* con): State::State(con){ cout << "S2()" << endl; // Start listen on Event Transition1 and Event Transmission2 Dispatcher* dsp = Dispatcher::getInstance(); dsp->addListener( this->con_, TRANSITION1); dsp->addListener( this->con_, TRANSITION2); }
Eater( Queue *q, std::string name) { this->handle = q; disp.registerHandler((Event::EventType)QueueEvents::EMPTY,this); disp.registerHandler((Event::EventType)QueueEvents::FULL,this); disp.registerHandler((Event::EventType)QueueEvents::NEW_VALUE,this); disp.registerHandler((Event::EventType)QueueEvents::END,this); this->name = name; }
void Dispatcher::Private::on_rem_timeout(DBusTimeout *timeout, void *data) { Dispatcher *d = static_cast<Dispatcher *>(data); Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout)); d->rem_timeout(t); }
void Dispatcher::Private::on_rem_watch(DBusWatch *watch, void *data) { Dispatcher *d = static_cast<Dispatcher *>(data); Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch)); d->rem_watch(w); }
int main(int argc, char* argv[]) { // Setup bad allocation handler std::set_new_handler(badAllocationHandler); #ifndef _WIN32 // ignore sigpipe... struct sigaction sigh; sigh.sa_handler = SIG_IGN; sigh.sa_flags = 0; sigemptyset(&sigh.sa_mask); sigaction(SIGPIPE, &sigh, nullptr); #endif ServiceManager serviceManager; g_dispatcher.start(); g_scheduler.start(); g_dispatcher.addTask(createTask(std::bind(mainLoader, argc, argv, &serviceManager))); g_loaderSignal.wait(g_loaderUniqueLock); if (serviceManager.is_running()) { std::cout << ">> " << g_config.getString(ConfigManager::SERVER_NAME) << " Server Online!" << std::endl << std::endl; #ifdef _WIN32 SetConsoleCtrlHandler([](DWORD) -> BOOL { g_dispatcher.addTask(createTask([]() { g_dispatcher.addTask(createTask( std::bind(&Game::shutdown, &g_game) )); g_scheduler.stop(); g_databaseTasks.stop(); g_dispatcher.stop(); })); ExitThread(0); }, 1); #endif serviceManager.run(); } else { std::cout << ">> No services running. The server is NOT online." << std::endl; g_dispatcher.addTask(createTask([]() { g_dispatcher.addTask(createTask([]() { g_scheduler.shutdown(); g_databaseTasks.shutdown(); g_dispatcher.shutdown(); })); g_scheduler.stop(); g_databaseTasks.stop(); g_dispatcher.stop(); })); } g_scheduler.join(); g_databaseTasks.join(); g_dispatcher.join(); return 0; }
int SvCon::onDisconnected(){ Dispatcher* d = getDispatcher(); d->delConnectServer(m_con_serv_id); ALogError(m_serv->getConfig().LogName) << "<action:server_disconnect> " "<event_loop:" << getEventLoop() << "> <conid:" << getId() << "> <con_serv_id:" << m_con_serv_id << ">"; return 0; }
void* dispatcher_resolve(dispatcher_t *obj, int sig[], int *count, int allow_unsafe, int exact_match_required) { Dispatcher *disp = static_cast<Dispatcher*>(obj); Type *args = reinterpret_cast<Type*>(sig); void *callable = disp->resolve(args, *count, (bool) allow_unsafe, (bool) exact_match_required); return callable; }
void dispatcher_add_defn(dispatcher_t *obj, int tys[], void* callable) { assert(sizeof(int) == sizeof(Type) && "Type should be representable by an int"); Dispatcher *disp = static_cast<Dispatcher*>(obj); Type *args = reinterpret_cast<Type*>(tys); disp->addDefinition(args, callable); }
void shouldBeAbleToGetListOfRegisteredObjectsAndClasses() { Dispatcher dispatcher; dispatcher.registerClass("class1", new ReturnObjectNameHandler()); dispatcher.registerObject("button1", new ObjectWithName("button1")); QCOMPARE(dispatcher.registeredObjects().size(), 1); QCOMPARE(dispatcher.registeredClasses().size(), 1); }
void shouldBeAbleToRegisterAnInvalidRequestHandler() { Dispatcher dispatcher; dispatcher.setInvalidRequestHandler(new ReturnNameHandler("invalid")); QCOMPARE(dispatcher.handleRequest("class1/click/button1"), QString("invalid")); QCOMPARE(dispatcher.handleRequest("class2/click/button1"), QString("invalid")); QCOMPARE(dispatcher.handleRequest("invalid"), QString("invalid")); }
void shouldBeAbleToUnregisterAnObject() { Dispatcher dispatcher; dispatcher.registerClass("class1", new ReturnObjectNameHandler()); dispatcher.registerObject("button1", new ObjectWithName("button1")); dispatcher.unRegisterObject("button1"); QCOMPARE(dispatcher.handleRequest("class1/click/button1"), QString("null")); }
int main (int argc, char* argv[]) { // We get the number of cores to be used. If we don't give any number, // we set to 0 which implies the usage of all available cores size_t nbCores = (argc >=2 ? atoi(argv[1]) : 0); // We create an iterator over an integer range int nmax = 10000; Range<int>::Iterator it (1,nmax); // We create a dispatcher configured for 'nbCores' cores. // The second argument tells how many consecutive values will be received by // each thread. The second argument tells how to group items per thread (set // here to 1 to emphasize concurrent access issue). Dispatcher dispatcher (nbCores, 1); // The idea here is to sum the integers of our range with an iteration. // (Note: we know that the result is N*(N+1)/2) int sum1=0, sum2=0; ////////////////////////////////////////////////// // First iteration: WRONG WAY ////////////////////////////////////////////////// // Our first attempt is to use an integer variable to sum the iterated value. // This variable will be shared by all the threads and, since they access to it // without caution wrt concurrent accesses, the sum result should be wrong (unless // you use one core only) dispatcher.iterate (it, [&] (int i) { sum1 += i; }); ////////////////////////////////////////////////// // Second iteration: CORRECT WAY ////////////////////////////////////////////////// // As previously, our second attempt will share the same integer variable. // But now, we take care about concurrent accesses with the use of the // __sync_fetch_and_add intrinsic instruction. This instruction ensures that // the shared integer can be modified by only one thread at one time. dispatcher.iterate (it, [&] (int i) { __sync_fetch_and_add (&sum2, i); }); ////////////////////////////////////////////////// // CONCLUSION ////////////////////////////////////////////////// cout << "First iteration: sum=" << sum1 << " (result should be " << nmax*(nmax+1)/2 << ")" << endl; cout << "Second iteration: sum=" << sum2 << " (result should be " << nmax*(nmax+1)/2 << ")" << endl; // Parallelization of Iterator is pretty simple with the Dispatcher class. // Moreover, usage of lambda expressions make the whole thing easy to write. // Note that the instruction block of the lambda expression doesn't even know that // it may be executed in different threads. In other words, the block doesn't refer // any stuff related to thread management; it just receives one of the item of the // iteration and process some action on it. // IMPORTANT ! As we have seen here, the user has to be aware that a shared resource (one // integer here) can be modified by several threads at the same time, so the user must use // some kind of synchronization for modifying the shared resource. We will see in other // examples that GATB provides mechanisms for this purpose. }
dbus_bool_t Dispatcher::Private::on_add_timeout(DBusTimeout *timeout, void *data) { Dispatcher *d = static_cast<Dispatcher *>(data); Timeout::Internal *t = reinterpret_cast<Timeout::Internal *>(timeout); d->add_timeout(t); return true; }
dbus_bool_t Dispatcher::Private::on_add_watch(DBusWatch *watch, void *data) { Dispatcher *d = static_cast<Dispatcher *>(data); Watch::Internal *w = reinterpret_cast<Watch::Internal *>(watch); d->add_watch(w); return true; }
void CartesianApp::eventLoop() { assert(screen); ScreenInfo* screen_info = screen->getInfo(); Rasterizer* ras = new Rasterizer(screen_info, screen->getWindowWidth(), screen->getWindowHeight()); PipelineXCBCartesian* pipeline = new PipelineXCBCartesian(ras, screen); FactoryManager fm; Dispatcher* dispatcher = fm.getDispatcherFactory()->create(pipeline, screen); dispatcher->start(); }