X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;ds=sidebyside;f=source%2Fpipe.cpp;h=b3735aa63b6d43a7724aaa13d1109ce96a78b0d2;hb=b97d4e9f86e90254ab9edef7ee62a910f6333c78;hp=88dd46210b844602c45ba0d12438a82100a7baac;hpb=c0861d1f8e3869f058bc8b152cd35a08e5b03e73;p=libs%2Fcore.git diff --git a/source/pipe.cpp b/source/pipe.cpp index 88dd462..b3735aa 100644 --- a/source/pipe.cpp +++ b/source/pipe.cpp @@ -13,25 +13,25 @@ namespace IO { Pipe::Pipe() { #ifdef WIN32 - string name=format("\\\\.\\pipe\\%u.%p", GetCurrentProcessId(), this); - handle[0]=CreateNamedPipe(name.c_str(), PIPE_ACCESS_INBOUND|FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE, 1, 1024, 1024, 0, 0); + string name = format("\\\\.\\pipe\\%u.%p", GetCurrentProcessId(), this); + handle[0] = CreateNamedPipe(name.c_str(), PIPE_ACCESS_INBOUND|FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE, 1, 1024, 1024, 0, 0); if(handle[0]==INVALID_HANDLE_VALUE) throw SystemError("Unable to create pipe", GetLastError()); - handle[1]=CreateFile(name.c_str(), GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); + handle[1] = CreateFile(name.c_str(), GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if(handle[1]==INVALID_HANDLE_VALUE) { - unsigned err=GetLastError(); + unsigned err = GetLastError(); CloseHandle(handle[0]); throw SystemError("Unable to create pipe", err); } - overlapped=0; - event=CreateEvent(0, true, false, 0); - buf_size=1024; - buffer=new char[buf_size]; - buf_avail=0; - buf_next=buffer; + overlapped = 0; + event = CreateEvent(0, true, false, 0); + buf_size = 1024; + buffer = new char[buf_size]; + buf_avail = 0; + buf_next = buffer; #else if(pipe(handle)==-1) throw SystemError("Unable to create pipe", errno); @@ -40,25 +40,16 @@ Pipe::Pipe() set_events(P_INPUT); } -void Pipe::set_block(bool b) +Pipe::~Pipe() { - mode=(mode&~M_NONBLOCK); - if(b) - mode=(mode|M_NONBLOCK); - -#ifndef WIN32 - int flags=fcntl(handle[0], F_GETFD); - fcntl(handle[0], F_SETFL, (flags&O_NONBLOCK)|(b?0:O_NONBLOCK)); - flags=fcntl(handle[1], F_GETFD); - fcntl(handle[1], F_SETFL, (flags&O_NONBLOCK)|(b?0:O_NONBLOCK)); -#endif + close(); } void Pipe::close() { set_events(P_NONE); - signal_closing.emit(); + signal_flush_required.emit(); #ifdef WIN32 CloseHandle(handle[0]); CloseHandle(handle[1]); @@ -69,43 +60,20 @@ void Pipe::close() #endif } -Handle Pipe::get_event_handle() +void Pipe::set_block(bool b) { -#ifdef WIN32 - if(!overlapped && !buf_avail) - { - overlapped=new OVERLAPPED; - memset(overlapped, 0, sizeof(OVERLAPPED)); - overlapped->hEvent=event; - - DWORD ret; - buf_next=buffer; - if(!ReadFile(handle[0], buffer, buf_size, &ret, overlapped)) - { - unsigned err=GetLastError(); - if(err!=ERROR_IO_PENDING) - throw SystemError("Failed to start an overlapped read", err); - } - else - { - buf_avail=ret; - delete overlapped; - overlapped=0; - SetEvent(event); - } - } + mode = (mode&~M_NONBLOCK); + if(b) + mode = (mode|M_NONBLOCK); - return event; -#else - return handle[0]; +#ifndef WIN32 + int flags = fcntl(handle[0], F_GETFD); + fcntl(handle[0], F_SETFL, (flags&O_NONBLOCK)|(b?0:O_NONBLOCK)); + flags = fcntl(handle[1], F_GETFD); + fcntl(handle[1], F_SETFL, (flags&O_NONBLOCK)|(b?0:O_NONBLOCK)); #endif } -Pipe::~Pipe() -{ - close(); -} - unsigned Pipe::do_write(const char *buf, unsigned size) { if(size==0) @@ -116,7 +84,7 @@ unsigned Pipe::do_write(const char *buf, unsigned size) if(!WriteFile(handle[1], buf, size, &ret, 0)) throw SystemError("Writing to pipe failed", GetLastError()); #else - int ret=::write(handle[1], buf, size); + int ret = ::write(handle[1], buf, size); if(ret==-1) { if(errno==EAGAIN) @@ -145,21 +113,21 @@ unsigned Pipe::do_read(char *buf, unsigned size) throw SystemError("Reading from pipe failed", GetLastError()); else { - buf_avail+=ret; + buf_avail += ret; delete overlapped; - overlapped=0; + overlapped = 0; } } - unsigned ret=min(buf_avail, size); + unsigned ret = min(buf_avail, size); memcpy(buf, buf_next, ret); - buf_next+=ret; - buf_avail-=ret; + buf_next += ret; + buf_avail -= ret; // Initiate another overlapped read in case someone is polling us get_event_handle(); #else - int ret=::read(handle[0], buf, size); + int ret = ::read(handle[0], buf, size); if(ret==-1) { if(errno==EAGAIN) @@ -171,12 +139,44 @@ unsigned Pipe::do_read(char *buf, unsigned size) if(ret==0) { - eof_flag=true; + eof_flag = true; signal_end_of_file.emit(); } return ret; } +Handle Pipe::get_event_handle() +{ +#ifdef WIN32 + if(!overlapped && !buf_avail) + { + overlapped = new OVERLAPPED; + memset(overlapped, 0, sizeof(OVERLAPPED)); + overlapped->hEvent = event; + + DWORD ret; + buf_next = buffer; + if(!ReadFile(handle[0], buffer, buf_size, &ret, overlapped)) + { + unsigned err = GetLastError(); + if(err!=ERROR_IO_PENDING) + throw SystemError("Failed to start an overlapped read", err); + } + else + { + buf_avail = ret; + delete overlapped; + overlapped = 0; + SetEvent(event); + } + } + + return event; +#else + return handle[0]; +#endif +} + } // namespace IO } // namespace Msp