Show
Ignore:
Timestamp:
07/07/08 21:41:05 (6 years ago)
Author:
kazuho
Message:

switch to edge-trigger-based design

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • lang/cplusplus/friends_framework/trunk/include/CoopSocket.h

    r15357 r15397  
    22#define COOPSOCKET_H 
    33 
     4#include <errno.h> 
     5#include <fcntl.h> 
    46#include <sys/types.h> 
    57#include <sys/socket.h> 
    68#include "CoopThread.h" 
    79#include "CoopBuffer.h" 
     10#include "CoopSocketMgr.h" 
    811 
    912class CoopSocket : public CoopThread { 
     13  friend class CoopSocketMgr; 
    1014public: 
    1115  enum { 
    12     WaitForRead = 0x1, 
    13     WaitForWrite = 0x2 
     16    WaitForRead    = 0x1, 
     17    WaitForWrite   = 0x2, 
     18    ReadBufIsEmpty = 0x4, 
     19    WriteBufIsFull = 0x8 
    1420  }; 
    1521protected: 
     
    1723  int state; 
    1824public: 
    19   CoopSocket(CoopThreadMgr *m) : CoopThread(m), sock(-1), state(0) {} 
     25  CoopSocket(CoopThreadMgr *m) : CoopThread(m), sock(-1), state(0) { 
     26  } 
    2027  virtual ~CoopSocket() { 
    21     if (sock != -1) 
     28    if (sock != -1) { 
     29      mgr->GetSocketMgr()->DetachThread(this); 
    2230      ::close(sock); 
     31    } 
    2332  } 
    2433  int GetSock() const { return sock; } 
    25   void SetSock(int s) { assert(sock == -1) ; sock = s; } 
    26   int GetState() const { return state; } 
    27   void SetState(int s) { state = s; } 
     34  void SetSock(int s) { 
     35    assert(sock == -1); 
     36    ::fcntl(s, F_SETFL, O_NONBLOCK); 
     37    sock = s; 
     38    mgr->GetSocketMgr()->AttachThread(this); 
     39  } 
     40  void SetWaitForRead() { state |= WaitForRead; } 
     41  void ClearWaitForRead() { state &= ~WaitForRead; } 
     42  void SetWaitForWrite() { state |= WaitForWrite; } 
     43  void ClearWaitForWrite() { state &= ~WaitForWrite; } 
    2844  int Accept(struct sockaddr *addr = NULL, socklen_t *addrlen = NULL) { 
    2945    return accept(sock, addr, addrlen); 
    3046  } 
    31   CoopBuffer Read() { 
    32     CoopBuffer buf; 
     47  bool Read(CoopBuffer &buf) { 
     48    if (buf.Size() != 0) 
     49      return true; 
     50    if ((state & ReadBufIsEmpty) != 0) 
     51      return true; 
    3352    ssize_t bytesRead = read(sock, buf.Bytes(), buf.Capacity()); 
    3453    if (bytesRead > 0) 
    35       buf.SetSize(bytesRead); 
    36     return buf; 
    37   } 
    38   bool Write(CoopBuffer& buf) { 
    39     ssize_t bytesWritten = write(sock, buf.Bytes(), buf.Size()); 
    40     if (bytesWritten <= 0) 
     54      buf.AdjustSize(bytesRead); 
     55    else if (bytesRead == -1 && errno == EAGAIN) 
     56      state |= ReadBufIsEmpty; 
     57    else 
    4158      return false; 
    42     buf.PopBytes(bytesWritten); 
    4359    return true; 
    4460  } 
    45   virtual void SetupSelect(int *nfds, fd_set *readFds, fd_set *writeFds, 
    46                            timeval *) { 
    47     if ((state & WaitForRead) != 0) { 
    48       *nfds = std::max(*nfds, sock + 1); 
    49       FD_SET(sock, readFds); 
    50     } 
    51     if ((state & WaitForWrite) != 0) { 
    52       *nfds = std::max(*nfds, sock + 1); 
    53       FD_SET(sock, writeFds); 
    54     } 
     61  bool Write(CoopBuffer &buf) { 
     62    if ((state & WriteBufIsFull) != 0) 
     63      return true; 
     64    ssize_t bytesWritten = write(sock, buf.Bytes(), buf.Size()); 
     65    if (bytesWritten > 0) 
     66      buf.PopBytes(bytesWritten); 
     67    else if (bytesWritten == -1 && errno == EAGAIN) 
     68        state |= WriteBufIsFull; 
     69    else 
     70      return false; 
     71    return true; 
    5572  } 
     73  virtual void Run(bool is_read) = 0; 
    5674}; 
    5775 
     
    6583                     void (Impl::*wf)(CoopSocket *)) 
    6684  : CoopSocket(m), impl(i), readf(rf), writef(wf) {} 
    67   virtual void Run(fd_set *readFds, fd_set *writeFds) { 
    68     if ((state & WaitForRead) != 0 && FD_ISSET(sock, readFds)) { 
     85  virtual void Run(bool is_read) { 
     86    if (is_read) 
    6987      (impl->*readf)(this); 
    70     } else if ((state & WaitForWrite) != 0 && FD_ISSET(sock, writeFds)) { 
     88    else 
    7189      (impl->*writef)(this); 
    72     } 
    7390  } 
    7491};