void IRCConnection::worker_main() { try { //clan::ConsoleWindow console("Debug"); clan::TCPConnection connection(server); connection.set_nodelay(true); connection.set_keep_alive(true, 60*1000, 60*1000); clan::Event read_event = connection.get_read_event(); clan::Event write_event = connection.get_write_event(); IRCRawString read_line, write_line; IRCRawString::size_type write_pos = 0; std::vector<clan::Event> wait_events; bool continue_loop = true; while (continue_loop) { wait_events.clear(); wait_events.push_back(read_event); if (write_line.length() != write_pos) wait_events.push_back(write_event); else wait_events.push_back(queues.send_event); wait_events.push_back(stop_event); int wakeup_reason = clan::Event::wait(wait_events, -1); if (wakeup_reason == 0) // read_event flagged { continue_loop = read_connection_data(connection, read_line); } else if (wakeup_reason == 1) // write_event / queues.send_event flagged { continue_loop = write_connection_data(write_line, write_pos, connection); } else // stop_event flagged { continue_loop = false; } } queues.set_disconnected(std::string()); set_wakeup_event(); } catch (clan::Exception &e) { queues.set_disconnected(e.message); set_wakeup_event(); } }
void WorkQueue_Impl::worker_main() { while (true) { int wakeup_reason = Event::wait(stop_event, work_available_event); if (wakeup_reason != 1) break; MutexSection mutex_lock(&mutex); if (!queued_items.empty()) { WorkItem *item = queued_items.front(); queued_items.erase(queued_items.begin()); mutex_lock.unlock(); item->process_work(); mutex_lock.lock(); finished_items.push_back(item); mutex_lock.unlock(); set_wakeup_event(); } else { work_available_event.reset(); } } }
void WorkQueue_Impl::work_completed(WorkItem *item) // transfers ownership { MutexSection mutex_lock(&mutex); finished_items.push_back(item); mutex_lock.unlock(); set_wakeup_event(); }
void timer_main() { while (true) { MutexSection mutex_lock(&mutex); update_event.reset(); if (stop_thread) break; ubyte64 current_time = System::get_time(); timeout = -1; bool found_timer = false; // Scan for timers to find the next one to call for (std::map<int, Timer_Object *>::iterator it = timer_objects.begin(); it != timer_objects.end(); ++it) { Timer_Object &object = *(it->second); if (!object.stopped) { if (!found_timer) { // First timer in the list timeout = object.end_time - current_time; found_timer = true; } else { // Get the smallest timeout int next_timeout = object.end_time - current_time; if (next_timeout < timeout) { timeout = next_timeout; } } // Force update, if a timer was missed if (timeout < 1) timeout = 1; } } mutex_lock.unlock(); if (Event::wait(update_event, timeout) == -1) set_wakeup_event(); } }
bool IRCConnection::read_connection_data(clan::TCPConnection &connection, IRCRawString &read_line) { char buffer[16*1024]; int data_read = connection.read(buffer, 16*1024, false); if (data_read == 0) // EOF from server { connection.disconnect_graceful(); return false; } int start_pos = 0; for (int i=0; i<data_read; i++) { if (buffer[i] == '\n') { read_line.append(buffer+start_pos, i-start_pos+1); start_pos = i+1; queues.push_received(read_line); set_wakeup_event(); read_line.clear(); } } read_line.append(buffer+start_pos, data_read-start_pos); return true; }