version 3.01
This commit is contained in:
parent
5ab09e78b2
commit
7adaaf99be
9 changed files with 214 additions and 112 deletions
|
@ -35,6 +35,7 @@ enum StreamMode
|
|||
StreamModeAccept,
|
||||
StreamModeRead,
|
||||
StreamModeWrite,
|
||||
StreamModeWait,
|
||||
StreamModeEnd
|
||||
};
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue