Changeset 18301 for lang/c/mpio/trunk/mp/fdnotify_impl.h
- Timestamp:
- 08/27/08 15:40:53 (4 months ago)
- Files:
-
- 1 modified
-
lang/c/mpio/trunk/mp/fdnotify_impl.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
lang/c/mpio/trunk/mp/fdnotify_impl.h
r18183 r18301 17 17 // 18 18 19 #ifndef MP_FD _NOTIFY_IMPL_H__20 #define MP_FD _NOTIFY_IMPL_H__19 #ifndef MP_FDNOTIFY_IMPL_H__ 20 #define MP_FDNOTIFY_IMPL_H__ 21 21 22 #include <sys/types.h>23 #include <sys/uio.h>24 #include <unistd.h>25 22 #include <fcntl.h> 26 23 #include <errno.h> … … 30 27 31 28 template <typename NotifyObject> 32 fdnotify<NotifyObject>::fdnotify() : m_ pos(0)29 fdnotify<NotifyObject>::fdnotify() : m_head(m_iovec), m_tail(m_iovec) 33 30 { 34 if( pipe(m_pipe) < 0 ) {31 if( ::pipe(m_pipe) < 0 ) { 35 32 throw fdnotify_exception("can't create pipe"); 36 33 } 37 if( fcntl(m_pipe[PIPE_READ], F_SETFL, O_NONBLOCK) < 0 ) {34 if( ::fcntl(m_pipe[0], F_SETFL, O_NONBLOCK) < 0 ) { 38 35 close(m_pipe[0]); 39 36 close(m_pipe[1]); 40 37 throw fdnotify_exception("can't set non-blocking mode"); 38 } 39 struct iovec* p = m_iovec; 40 struct iovec* const endp = m_iovec + MP_FDNOTIFY_VECTOR_SIZE; 41 NotifyObject* b = (NotifyObject*)m_buffer; 42 for(; p != endp; ++p, ++b) { 43 p->iov_base = (char*)b; 44 p->iov_len = sizeof(NotifyObject); 41 45 } 42 46 } … … 50 54 51 55 template <typename NotifyObject> 52 bool fdnotify<NotifyObject>::try_receive(NotifyObject* result)56 inline bool fdnotify<NotifyObject>::try_receive(NotifyObject* result) 53 57 { 54 ssize_t len = read(m_pipe[PIPE_READ], m_buffer + m_pos, sizeof(NotifyObject) - m_pos); 55 if( len < 0 ) { 56 if(errno == EAGAIN || errno == EINTR ) { 58 if(m_head < m_tail) { 59 *result = *((NotifyObject*)m_head->iov_base); 60 ++m_head; 61 return true; 62 } else { 63 return receive_next(result); 64 } 65 } 66 67 template <typename NotifyObject> 68 inline void fdnotify<NotifyObject>::send(const NotifyObject& obj) 69 { 70 ssize_t len = ::write(m_pipe[1], (void*)&obj, sizeof(NotifyObject)); 71 if(len != sizeof(NotifyObject)) { 72 throw fdnotify_exception("write-side pipe is broken or closed"); 73 } 74 } 75 76 template <typename NotifyObject> 77 bool fdnotify<NotifyObject>::receive_next(NotifyObject* result) 78 { 79 ssize_t len = ::readv(m_pipe[0], m_iovec, MP_FDNOTIFY_VECTOR_SIZE); 80 if(len < 0) { 81 if(errno == EAGAIN || errno == EINTR) { 57 82 return false; 58 83 } else { 59 84 throw fdnotify_exception("read-side pipe is broken"); 60 85 } 61 } else if( len == 0) {86 } else if(len == 0) { 62 87 throw fdnotify_exception("read-side pipe is closed"); 63 88 } 64 65 m_pos += len; 66 if( m_pos == sizeof(NotifyObject) ) { 67 *result = *reinterpret_cast<NotifyObject*>(m_buffer); 68 m_pos = 0; 69 return true; 89 if(static_cast<size_t>(len) > sizeof(NotifyObject)) { 90 m_head = m_iovec+1; 91 m_tail = (struct iovec*)(((char*)m_iovec) + len); 70 92 } 71 return false; 72 } 73 74 75 template <typename NotifyObject> 76 void fdnotify<NotifyObject>::send(const NotifyObject& obj) 77 { 78 const char* p = reinterpret_cast<const char*>(&obj); 79 ssize_t len = ::write(m_pipe[PIPE_WRITE], p, sizeof(NotifyObject)); 80 if( len < static_cast<ssize_t>(sizeof(NotifyObject)) ) { 81 if( len < 0 && errno != EINTR && errno != EAGAIN ) { 82 throw fdnotify_exception("write-side pipe is broken"); 83 } 84 send_all(p, p + sizeof(NotifyObject) - len); 85 } 86 } 87 88 89 template <typename NotifyObject> 90 void fdnotify<NotifyObject>::send_all(const char* p, const char* const endp) 91 { 92 do { 93 ssize_t len = ::write(m_pipe[PIPE_WRITE], p, endp - p); 94 if( len < 0 ) { 95 if( errno != EINTR && errno != EAGAIN ) { 96 throw fdnotify_exception("write-side pipe is broken"); 97 } 98 } else if( len == 0 ) { 99 throw fdnotify_exception("write-side pipe is closed"); 100 } else { 101 p += len; 102 } 103 } while( p < endp ); 93 *result = *((NotifyObject*)m_iovec[0].iov_base); 94 return true; 104 95 } 105 96
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)