- Timestamp:
- 07/07/08 21:41:05 (5 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
lang/cplusplus/friends_framework/trunk/include/CoopSocket.h
r15357 r15397 2 2 #define COOPSOCKET_H 3 3 4 #include <errno.h> 5 #include <fcntl.h> 4 6 #include <sys/types.h> 5 7 #include <sys/socket.h> 6 8 #include "CoopThread.h" 7 9 #include "CoopBuffer.h" 10 #include "CoopSocketMgr.h" 8 11 9 12 class CoopSocket : public CoopThread { 13 friend class CoopSocketMgr; 10 14 public: 11 15 enum { 12 WaitForRead = 0x1, 13 WaitForWrite = 0x2 16 WaitForRead = 0x1, 17 WaitForWrite = 0x2, 18 ReadBufIsEmpty = 0x4, 19 WriteBufIsFull = 0x8 14 20 }; 15 21 protected: … … 17 23 int state; 18 24 public: 19 CoopSocket(CoopThreadMgr *m) : CoopThread(m), sock(-1), state(0) {} 25 CoopSocket(CoopThreadMgr *m) : CoopThread(m), sock(-1), state(0) { 26 } 20 27 virtual ~CoopSocket() { 21 if (sock != -1) 28 if (sock != -1) { 29 mgr->GetSocketMgr()->DetachThread(this); 22 30 ::close(sock); 31 } 23 32 } 24 33 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; } 28 44 int Accept(struct sockaddr *addr = NULL, socklen_t *addrlen = NULL) { 29 45 return accept(sock, addr, addrlen); 30 46 } 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; 33 52 ssize_t bytesRead = read(sock, buf.Bytes(), buf.Capacity()); 34 53 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 41 58 return false; 42 buf.PopBytes(bytesWritten);43 59 return true; 44 60 } 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; 55 72 } 73 virtual void Run(bool is_read) = 0; 56 74 }; 57 75 … … 65 83 void (Impl::*wf)(CoopSocket *)) 66 84 : 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) 69 87 (impl->*readf)(this); 70 } else if ((state & WaitForWrite) != 0 && FD_ISSET(sock, writeFds)) {88 else 71 89 (impl->*writef)(this); 72 }73 90 } 74 91 };
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)