version 3.01

This commit is contained in:
Bramfeld Team 2016-02-19 14:27:00 +01:00
parent 5ab09e78b2
commit 7adaaf99be
9 changed files with 214 additions and 112 deletions

View file

@ -35,6 +35,7 @@ enum StreamMode
StreamModeAccept,
StreamModeRead,
StreamModeWrite,
StreamModeWait,
StreamModeEnd
};

View file

@ -19,7 +19,7 @@
IoService::IoService () : Thread ("IoService"), log_ ("/io/thread")
{
handle_ = rfd_ = wfd_ = -1;
timeout_ = handle_ = rfd_ = wfd_ = -1;
int fd[2];
if (::pipe (fd) == 0)
@ -54,7 +54,10 @@ void IoService::main ()
cancel (msg.action);
}
poll (-1);
poll (timeout_);
if (timeout_ > 0)
wakeup_readers ();
}
set_fd (rfd_, -1, 0);
@ -81,32 +84,40 @@ void IoService::handle_request (EventAction* act)
schedule (act);
else
track (act);
return;
break;
case StreamModeAccept:
track (act);
return;
break;
case StreamModeRead:
if (read_channel (act->fd_, (act->callback_ ? act->callback_->param () : ev), 1))
schedule (act);
else
track (act);
return;
break;
case StreamModeWrite:
if (write_channel (act->fd_, (act->callback_ ? act->callback_->param () : ev)))
schedule (act);
else
track (act);
return;
break;
case StreamModeWait:
{
WaitNode node = {current_time () + act->fd_, act};
wait_list_.insert (wait_list_.end (), node);
timeout_ = IO_POLL_TIMEOUT;
}
break;
case StreamModeEnd:
if (close_channel (act->fd_, (act->callback_ ? act->callback_->param () : ev)))
schedule (act);
else
track (act);
return;
break;
}
}
}
@ -125,6 +136,7 @@ bool IoService::connect_channel (int fd, Event& ev)
case 0:
ev.type_ = Event::Done;
break;
case -1:
switch (errno)
{
@ -279,43 +291,65 @@ void IoService::track (EventAction* act)
void IoService::cancel (EventAction* act)
{
std::map<int, IoNode>::iterator it;
int fd;
std::deque<WaitNode>::iterator w;
if (act)
{
fd = act->fd_;
it = fd_map_.find (fd);
switch (act->mode_)
{
case StreamModeAccept:
case StreamModeRead:
it = fd_map_.find (act->fd_);
if (it != fd_map_.end () && it->second.read_action == act)
{
it->second.reading = false, it->second.read_action = 0;
if (it->second.write_action == 0)
fd_map_.erase (it);
set_fd (fd, -1, (it->second.writing ? 2 : 0), &it->second);
set_fd (act->fd_, -1, (it->second.writing ? 2 : 0), &it->second);
}
break;
case StreamModeConnect:
case StreamModeWrite:
case StreamModeEnd:
it = fd_map_.find (act->fd_);
if (it != fd_map_.end () && it->second.write_action == act)
{
it->second.writing = false, it->second.write_action = 0;
if (it->second.read_action == 0)
fd_map_.erase (it);
set_fd (fd, (it->second.reading ? 2 : 0), -1, &it->second);
set_fd (act->fd_, (it->second.reading ? 2 : 0), -1, &it->second);
}
break;
case StreamModeWait:
for (w = wait_list_.begin (); w != wait_list_.end (); ++w)
{
if (w->action == act)
{
wait_list_.erase (w);
break;
}
}
if (wait_list_.empty ())
timeout_ = -1;
break;
}
terminate (act);
}
}
void IoService::wakeup_readers ()
{
std::deque<WaitNode>::iterator w;
long t = current_time ();
for (w = wait_list_.begin (); w != wait_list_.end (); ++w)
if (w->limit > 0 && w->limit <= t)
schedule (w->action), w->limit = 0;
}
void IoService::schedule (EventAction* act)
{
EventMessage msg = {1, act};

View file

@ -12,7 +12,9 @@
#define EVENT_IO_SERVICE_H
#include <unistd.h>
#include <sys/time.h>
#include <map>
#include <deque>
#include <common/buffer.h>
#include <common/ring_buffer.h>
#include <common/thread/thread.h>
@ -22,6 +24,7 @@
#define IO_READ_BUFFER_SIZE 0x10000
#define IO_POLL_EVENT_COUNT 512
#define IO_POLL_TIMEOUT 150
struct IoNode
{
@ -32,6 +35,12 @@ struct IoNode
EventAction* write_action;
};
struct WaitNode
{
long limit;
EventAction* action;
};
class IoService : public Thread
{
private:
@ -39,7 +48,10 @@ private:
RingBuffer<EventMessage> gateway_;
uint8_t read_pool_[IO_READ_BUFFER_SIZE];
std::map<int, IoNode> fd_map_;
int handle_, rfd_, wfd_;
std::deque<WaitNode> wait_list_;
int timeout_;
int handle_;
int rfd_, wfd_;
public:
IoService ();
@ -56,6 +68,7 @@ private:
bool close_channel (int fd, Event& ev);
void track (EventAction* act);
void cancel (EventAction* act);
void wakeup_readers ();
void schedule (EventAction* act);
void terminate (EventAction* act);
@ -68,6 +81,8 @@ public:
bool idle () const { return fd_map_.empty (); }
void wakeup () { ::write (wfd_, "*", 1); }
void take_message (const EventMessage& msg) { gateway_.write (msg); wakeup (); }
long current_time () { struct timeval tv; gettimeofday (&tv, 0);
return ((tv.tv_sec & 0xFF) * 1000 + tv.tv_usec / 1000); }
};
#endif /* !EVENT_IO_SERVICE_H */