Example #1
0
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();
	}
}
Example #2
0
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();
		}
	}
}
Example #3
0
void WorkQueue_Impl::work_completed(WorkItem *item) // transfers ownership
{
	MutexSection mutex_lock(&mutex);
	finished_items.push_back(item);
	mutex_lock.unlock();
	set_wakeup_event();
}
Example #4
0
	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();
		}
	}
Example #5
0
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;
}