Jack2  1.9.9
JackWinNamedPipeClientChannel.cpp
1 /*
2  Copyright (C) 2004-2008 Grame
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU Lesser General Public License as published by
6  the Free Software Foundation; either version 2.1 of the License, or
7  (at your option) any later version.
8 
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 Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 
18  */
19 
20 
21 #include "JackWinNamedPipeClientChannel.h"
22 #include "JackRequest.h"
23 #include "JackClient.h"
24 #include "JackGlobals.h"
25 #include "JackError.h"
26 
27 namespace Jack
28 {
29 
30 JackWinNamedPipeClientChannel::JackWinNamedPipeClientChannel()
31  :JackGenericClientChannel(),fThread(this)
32 {
33  fRequest = new JackWinNamedPipeClient();
34 }
35 
36 JackWinNamedPipeClientChannel::~JackWinNamedPipeClientChannel()
37 {
38  delete fRequest;
39 }
40 
41 int JackWinNamedPipeClientChannel::Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status)
42 {
43  int result = 0;
44  jack_log("JackWinNamedPipeClientChannel::Open name = %s", name);
45 
46  /*
47  16/08/07: was called before doing "fRequest->Connect" .... still necessary?
48  if (fNotificationListenPipe.Bind(jack_client_dir, name, 0) < 0) {
49  jack_error("Cannot bind pipe");
50  goto error;
51  }
52  */
53 
54  if (fRequest->Connect(jack_server_dir, server_name, 0) < 0) {
55  jack_error("Cannot connect to server pipe");
56  goto error;
57  }
58 
59  // Check name in server
60  ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, true);
61  if (result < 0) {
62  int status1 = *status;
63  if (status1 & JackVersionError) {
64  jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
65  } else {
66  jack_error("Client name = %s conflits with another running client", name);
67  }
68  }
69 
70  if (fNotificationListenPipe.Bind(jack_client_dir, name_res, 0) < 0) {
71  jack_error("Cannot bind pipe");
72  goto error;
73  }
74 
75  fClient = obj;
76  return 0;
77 
78 error:
79  fRequest->Close();
80  fNotificationListenPipe.Close();
81  return -1;
82 }
83 
84 void JackWinNamedPipeClientChannel::Close()
85 {
86  fRequest->Close();
87  fNotificationListenPipe.Close();
88  // Here the thread will correctly stop when the pipe are closed
89  fThread.Stop();
90 }
91 
92 int JackWinNamedPipeClientChannel::Start()
93 {
94  jack_log("JackWinNamedPipeClientChannel::Start");
95  /*
96  To be sure notification thread is started before ClientOpen is called.
97  */
98  if (fThread.StartSync() != 0) {
99  jack_error("Cannot start Jack client listener");
100  return -1;
101  } else {
102  return 0;
103  }
104 }
105 
106 void JackWinNamedPipeClientChannel::Stop()
107 {
108  jack_log("JackWinNamedPipeClientChannel::Stop");
109  fThread.Kill(); // Unsafe on WIN32... TODO : solve WIN32 thread Kill issue
110 }
111 
113 {
114  jack_log("JackWinNamedPipeClientChannel::Init");
115 
116  // Setup context
117  if (!jack_tls_set(JackGlobals::fNotificationThread, this)) {
118  jack_error("Failed to set thread notification key");
119  }
120 
121  if (!fNotificationListenPipe.Accept()) {
122  jack_error("JackWinNamedPipeClientChannel: cannot establish notification pipe");
123  return false;
124  } else {
125  return true;
126  }
127 }
128 
129 bool JackWinNamedPipeClientChannel::Execute()
130 {
132  JackResult res;
133 
134  if (event.Read(&fNotificationListenPipe) < 0) {
135  jack_error("JackWinNamedPipeClientChannel read fail");
136  goto error;
137  }
138 
139  res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fMessage, event.fValue1, event.fValue2);
140 
141  if (event.fSync) {
142  if (res.Write(&fNotificationListenPipe) < 0) {
143  jack_error("JackWinNamedPipeClientChannel write fail");
144  goto error;
145  }
146  }
147  return true;
148 
149 error:
150  // Close the pipes, server wont be able to create them otherwise.
151  fNotificationListenPipe.Close();
152  fRequest->Close();
153  fClient->ShutDown();
154  return false;
155 }
156 
157 } // end of namespace
158 
159 
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:91
Result from the server.
Definition: JackRequest.h:129
SERVER_EXPORT void jack_log(const char *fmt,...)
Definition: JackError.cpp:107
ClientNotification.
Definition: JackRequest.h:1569