Correct target
[jack2.git] / windows / JackWinNamedPipe.cpp
blob243916ec05879dacf7ad53ed8174dd8e1fa06caa
1 /*
2 Copyright (C) 2004-2006 Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "JackWinNamedPipe.h"
21 #include "JackError.h"
22 #include <assert.h>
24 #define BUFSIZE 4096
26 namespace Jack
29 int JackWinNamedPipe::Read(void* data, int len)
31 DWORD read;
32 JackLog("JackWinNamedPipeClient::Read len = %ld\n", len);
33 BOOL res = ReadFile(fNamedPipe, data, len, &read, NULL);
34 JackLog("JackWinNamedPipeClient::Read res = %ld read %ld\n", res, read);
35 if (read != len) {
36 jack_error("Cannot read named pipe err = %ld", GetLastError());
37 return -1;
38 } else {
39 return 0;
43 int JackWinNamedPipe::Write(void* data, int len)
45 DWORD written;
46 JackLog("JackWinNamedPipeClient::Write len = %ld\n", len);
47 BOOL res = WriteFile(fNamedPipe, data, len, &written, NULL);
48 if (written != len) {
49 jack_error("Cannot write named pipe err = %ld", GetLastError());
50 return -1;
51 } else {
52 return 0;
56 int JackWinNamedPipeClient::Connect(const char* dir, int which)
58 sprintf(fName, "\\\\.\\pipe\\%s_jack_%d", dir, which);
59 JackLog("Connect: fName %s\n", fName);
61 fNamedPipe = CreateFile(fName, // pipe name
62 GENERIC_READ | // read and write access
63 GENERIC_WRITE,
64 0, // no sharing
65 NULL, // default security attributes
66 OPEN_EXISTING, // opens existing pipe
67 0, // default attributes
68 NULL); // no template file
70 if (fNamedPipe == INVALID_HANDLE_VALUE) {
71 jack_error("Cannot connect to named pipe = %s err = %ld", fName, GetLastError());
72 return -1;
73 } else {
74 return 0;
78 int JackWinNamedPipeClient::Connect(const char* dir, const char* name, int which)
80 sprintf(fName, "\\\\.\\pipe\\%s_jack_%s", dir, name);
81 JackLog("Connect: fName %s\n", fName);
83 fNamedPipe = CreateFile(fName, // pipe name
84 GENERIC_READ | // read and write access
85 GENERIC_WRITE,
86 0, // no sharing
87 NULL, // default security attributes
88 OPEN_EXISTING, // opens existing pipe
89 0, // default attributes
90 NULL); // no template file
92 if (fNamedPipe == INVALID_HANDLE_VALUE) {
93 jack_error("Cannot connect to named pipe = %s err = %ld", fName, GetLastError());
94 return -1;
95 } else {
96 return 0;
100 int JackWinNamedPipeClient::Close()
102 CloseHandle(fNamedPipe);
103 return 0;
106 void JackWinNamedPipeClient::SetReadTimeOut(long sec)
109 void JackWinNamedPipeClient::SetWriteTimeOut(long sec)
113 JackWinAsyncNamedPipeClient::JackWinAsyncNamedPipeClient()
114 : JackWinNamedPipeClient(), fIOState(kIdle), fPendingIO(false)
116 fIOState = kIdle;
117 fOverlap.hEvent = CreateEvent(NULL, // default security attribute
118 TRUE, // manual-reset event
119 TRUE, // initial state = signaled
120 NULL); // unnamed event object
123 JackWinAsyncNamedPipeClient::JackWinAsyncNamedPipeClient(HANDLE pipe, bool pending)
124 : JackWinNamedPipeClient(pipe), fIOState(kIdle), fPendingIO(pending)
126 fOverlap.hEvent = CreateEvent(NULL, // default security attribute
127 TRUE, // manual-reset event
128 TRUE, // initial state = signaled
129 NULL); // unnamed event object
131 if (!fPendingIO)
132 SetEvent(fOverlap.hEvent);
134 fIOState = (fPendingIO) ? kConnecting : kReading;
137 JackWinAsyncNamedPipeClient::~JackWinAsyncNamedPipeClient()
139 CloseHandle(fOverlap.hEvent);
142 int JackWinAsyncNamedPipeClient::FinishIO()
144 DWORD success, ret;
145 success = GetOverlappedResult(fNamedPipe, // handle to pipe
146 &fOverlap, // OVERLAPPED structure
147 &ret, // bytes transferred
148 FALSE); // do not wait
150 switch (fIOState) {
152 case kConnecting:
153 if (!success) {
154 jack_error("Conection error");
155 return -1;
156 } else {
157 fIOState = kReading;
158 // Prepare connection for new client ??
160 break;
162 case kReading:
163 if (!success || ret == 0) {
164 return -1;
166 fIOState = kWriting;
167 break;
169 case kWriting:
170 if (!success || ret == 0) {
171 return -1;
173 fIOState = kReading;
174 break;
177 return 0;
180 int JackWinAsyncNamedPipeClient::Read(void* data, int len)
182 DWORD read;
183 JackLog("JackWinNamedPipeClient::Read len = %ld\n", len);
184 BOOL res = ReadFile(fNamedPipe, data, len, &read, &fOverlap);
185 JackLog("JackWinNamedPipeClient::Read res = %ld read %ld\n", res, read);
187 if (res && read != 0) {
188 fPendingIO = false;
189 fIOState = kWriting;
190 return 0;
191 } else if (!res && GetLastError() == ERROR_IO_PENDING) {
192 fPendingIO = true;
193 return 0;
194 } else {
195 jack_error("Cannot read named pipe err = %ld", GetLastError());
196 return -1;
200 int JackWinAsyncNamedPipeClient::Write(void* data, int len)
202 DWORD written;
203 JackLog("JackWinNamedPipeClient::Write len = %ld\n", len);
204 BOOL res = WriteFile(fNamedPipe, data, len, &written, &fOverlap);
206 if (res && written != 0) {
207 fPendingIO = false;
208 fIOState = kWriting;
209 return 0;
210 } else if (!res && GetLastError() == ERROR_IO_PENDING) {
211 fPendingIO = true;
212 return 0;
213 } else {
214 jack_error("Cannot write named pipe err = %ld", GetLastError());
215 return -1;
219 // Server side
221 int JackWinNamedPipeServer::Bind(const char* dir, int which)
223 sprintf(fName, "\\\\.\\pipe\\%s_jack_%d", dir, which);
224 JackLog("Bind: fName %s\n", fName);
226 if ((fNamedPipe = CreateNamedPipe(fName,
227 PIPE_ACCESS_DUPLEX, // read/write access
228 PIPE_TYPE_MESSAGE | // message type pipe
229 PIPE_READMODE_MESSAGE | // message-read mode
230 PIPE_WAIT, // blocking mode
231 PIPE_UNLIMITED_INSTANCES, // max. instances
232 BUFSIZE, // output buffer size
233 BUFSIZE, // input buffer size
234 INFINITE, // client time-out
235 NULL)) == INVALID_HANDLE_VALUE) { // no security a
236 jack_error("Cannot bind server to pipe err = %ld", GetLastError());
237 return -1;
238 } else {
239 return 0;
243 int JackWinNamedPipeServer::Bind(const char* dir, const char* name, int which)
245 sprintf(fName, "\\\\.\\pipe\\%s_jack_%s", dir, name);
246 JackLog("Bind: fName %s\n", fName);
248 if ((fNamedPipe = CreateNamedPipe(fName,
249 PIPE_ACCESS_DUPLEX, // read/write access
250 PIPE_TYPE_MESSAGE | // message type pipe
251 PIPE_READMODE_MESSAGE | // message-read mode
252 PIPE_WAIT, // blocking mode
253 PIPE_UNLIMITED_INSTANCES, // max. instances
254 BUFSIZE, // output buffer size
255 BUFSIZE, // input buffer size
256 INFINITE, // client time-out
257 NULL)) == INVALID_HANDLE_VALUE) { // no security a
258 jack_error("Cannot bind server to pipe err = %ld", GetLastError());
259 return -1;
260 } else {
261 return 0;
265 bool JackWinNamedPipeServer::Accept()
267 if (ConnectNamedPipe(fNamedPipe, NULL)) {
268 return true;
269 } else {
270 jack_error("Cannot bind server pipe name = %s err = %ld", fName, GetLastError());
271 if (GetLastError() == ERROR_PIPE_CONNECTED) {
272 jack_error("pipe already connnected = %s ", fName);
273 return true;
274 } else {
275 return false;
280 JackWinNamedPipeClient* JackWinNamedPipeServer::AcceptClient()
282 if (ConnectNamedPipe(fNamedPipe, NULL)) {
283 return new JackWinNamedPipeClient(fNamedPipe);
284 } else {
285 switch (GetLastError()) {
287 case ERROR_PIPE_CONNECTED:
288 return new JackWinNamedPipeClient(fNamedPipe);
290 default:
291 jack_error("Cannot connect server pipe name = %s err = %ld", fName, GetLastError());
292 return NULL;
293 break;
298 int JackWinNamedPipeServer::Close()
300 DisconnectNamedPipe(fNamedPipe);
301 CloseHandle(fNamedPipe);
302 return 0;
305 // Server side
307 int JackWinAsyncNamedPipeServer::Bind(const char* dir, int which)
309 sprintf(fName, "\\\\.\\pipe\\%s_jack_%d", dir, which);
310 JackLog("Bind: fName %s\n", fName);
312 if ((fNamedPipe = CreateNamedPipe(fName,
313 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // read/write access
314 PIPE_TYPE_MESSAGE | // message type pipe
315 PIPE_READMODE_MESSAGE | // message-read mode
316 PIPE_WAIT, // blocking mode
317 PIPE_UNLIMITED_INSTANCES, // max. instances
318 BUFSIZE, // output buffer size
319 BUFSIZE, // input buffer size
320 INFINITE, // client time-out
321 NULL)) == INVALID_HANDLE_VALUE) { // no security a
322 jack_error("Cannot bind server to pipe err = %ld", GetLastError());
323 return -1;
324 } else {
325 return 0;
329 int JackWinAsyncNamedPipeServer::Bind(const char* dir, const char* name, int which)
331 sprintf(fName, "\\\\.\\pipe\\%s_jack_%s", dir, name);
332 JackLog("Bind: fName %s\n", fName);
334 if ((fNamedPipe = CreateNamedPipe(fName,
335 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // read/write access
336 PIPE_TYPE_MESSAGE | // message type pipe
337 PIPE_READMODE_MESSAGE | // message-read mode
338 PIPE_WAIT, // blocking mode
339 PIPE_UNLIMITED_INSTANCES, // max. instances
340 BUFSIZE, // output buffer size
341 BUFSIZE, // input buffer size
342 INFINITE, // client time-out
343 NULL)) == INVALID_HANDLE_VALUE) { // no security a
344 jack_error("Cannot bind server to pipe err = %ld", GetLastError());
345 return -1;
346 } else {
347 return 0;
351 JackWinNamedPipeClient* JackWinAsyncNamedPipeServer::AcceptClient()
353 if (ConnectNamedPipe(fNamedPipe, NULL)) {
354 return new JackWinAsyncNamedPipeClient(fNamedPipe, false);
355 } else {
356 switch (GetLastError()) {
358 case ERROR_IO_PENDING:
359 return new JackWinAsyncNamedPipeClient(fNamedPipe, true);
361 case ERROR_PIPE_CONNECTED:
362 return new JackWinAsyncNamedPipeClient(fNamedPipe, false);
364 default:
365 jack_error("Cannot connect server pipe name = %s err = %ld", fName, GetLastError());
366 return NULL;
367 break;
372 } // end of namespace