5 #include <msp/core/systemerror.h>
6 #include <msp/strings/formatter.h>
7 #include "handle_private.h"
18 OVERLAPPED *overlapped;
32 string name = format("\\\\.\\pipe\\%u.%p", GetCurrentProcessId(), this);
33 *handle[0] = CreateNamedPipe(name.c_str(), PIPE_ACCESS_INBOUND|FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE, 1, 1024, 1024, 0, 0);
35 throw system_error("CreateNamedPipe");
37 *handle[1] = CreateFile(name.c_str(), GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
40 unsigned err = GetLastError();
41 CloseHandle(*handle[0]);
42 throw system_error(format("CreateFile(%s)", name), err);
47 *priv->event = CreateEvent(0, true, false, 0);
48 priv->buf_size = 1024;
49 priv->buffer = new char[priv->buf_size];
51 priv->buf_next = priv->buffer;
55 throw system_error("pipe");
57 *handle[0] = pipe_fd[0];
58 *handle[1] = pipe_fd[1];
68 CloseHandle(*priv->event);
78 signal_flush_required.emit();
84 void Pipe::set_block(bool b)
86 mode = (mode&~M_NONBLOCK);
88 mode = (mode|M_NONBLOCK);
91 int flags = fcntl(*handle[0], F_GETFD);
92 fcntl(*handle[0], F_SETFL, (flags&O_NONBLOCK)|(b?0:O_NONBLOCK));
93 flags = fcntl(*handle[1], F_GETFD);
94 fcntl(*handle[1], F_SETFL, (flags&O_NONBLOCK)|(b?0:O_NONBLOCK));
98 unsigned Pipe::do_write(const char *buf, unsigned size)
103 return sys_write(handle[1], buf, size);
106 unsigned Pipe::do_read(char *buf, unsigned size)
112 // Initiate overlapped read if needed
118 if(!GetOverlappedResult(*handle[0], priv->overlapped, &ret, !priv->buf_avail))
119 throw system_error("GetOverlappedResult");
122 priv->buf_avail += ret;
123 delete priv->overlapped;
124 priv->overlapped = 0;
128 unsigned ret = min(priv->buf_avail, size);
129 memcpy(buf, priv->buf_next, ret);
130 priv->buf_next += ret;
131 priv->buf_avail -= ret;
133 // Initiate another overlapped read in case someone is polling us
136 unsigned ret = sys_read(handle[0], buf, size);
142 signal_end_of_file.emit();
148 const Handle &Pipe::get_event_handle()
151 if(!priv->overlapped && !priv->buf_avail)
153 priv->overlapped = new OVERLAPPED;
154 memset(priv->overlapped, 0, sizeof(OVERLAPPED));
155 priv->overlapped->hEvent = *priv->event;
158 priv->buf_next = priv->buffer;
159 if(!ReadFile(*handle[0], priv->buffer, priv->buf_size, &ret, priv->overlapped))
161 unsigned err = GetLastError();
162 if(err!=ERROR_IO_PENDING)
163 throw system_error("ReadFile");
167 priv->buf_avail = ret;
168 delete priv->overlapped;
169 priv->overlapped = 0;
170 SetEvent(*priv->event);