Jack2 1.9.12

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* client, 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 // Before any server/client call
55 fClient = client;
56
57 if (fRequest->Connect(jack_server_dir, server_name, 0) < 0) {
58 jack_error("Cannot connect to server pipe");
59 goto error;
60 }
61
62 // OK so server is there...
63 JackGlobals::fServerRunning = true;
64
65 // Check name in server
66 ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, true);
67 if (result < 0) {
68 int status1 = *status;
69 if (status1 & JackVersionError) {
70 jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
71 } else {
72 jack_error("Client name = %s conflits with another running client", name);
73 }
74 }
75
76 if (fNotificationListenPipe.Bind(jack_client_dir, name_res, 0) < 0) {
77 jack_error("Cannot bind pipe");
78 goto error;
79 }
80
81 return 0;
82
83 error:
84 fRequest->Close();
85 fNotificationListenPipe.Close();
86 return -1;
87 }
88
89 void JackWinNamedPipeClientChannel::Close()
90 {
91 fRequest->Close();
92 fNotificationListenPipe.Close();
93 // Here the thread will correctly stop when the pipe are closed
94 fThread.Stop();
95 }
96
97 int JackWinNamedPipeClientChannel::Start()
98 {
99 jack_log("JackWinNamedPipeClientChannel::Start");
100 /*
101 To be sure notification thread is started before ClientOpen is called.
102 */
103 if (fThread.StartSync() != 0) {
104 jack_error("Cannot start Jack client listener");
105 return -1;
106 } else {
107 return 0;
108 }
109 }
110
111 void JackWinNamedPipeClientChannel::Stop()
112 {
113 jack_log("JackWinNamedPipeClientChannel::Stop");
114 fThread.Kill(); // Unsafe on WIN32... TODO : solve WIN32 thread Kill issue
115 }
116
117 bool JackWinNamedPipeClientChannel::Init()
118 {
119 jack_log("JackWinNamedPipeClientChannel::Init");
120
121 // Setup context
122 if (!jack_tls_set(JackGlobals::fNotificationThread, this)) {
123 jack_error("Failed to set thread notification key");
124 }
125
126 if (!fNotificationListenPipe.Accept()) {
127 jack_error("JackWinNamedPipeClientChannel: cannot establish notification pipe");
128 return false;
129 } else {
130 return true;
131 }
132 }
133
134 bool JackWinNamedPipeClientChannel::Execute()
135 {
136 JackClientNotification event;
137 JackResult res;
138
139 if (event.Read(&fNotificationListenPipe) < 0) {
140 jack_error("JackWinNamedPipeClientChannel read fail");
141 goto error;
142 }
143
144 res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fMessage, event.fValue1, event.fValue2);
145
146 if (event.fSync) {
147 if (res.Write(&fNotificationListenPipe) < 0) {
148 jack_error("JackWinNamedPipeClientChannel write fail");
149 goto error;
150 }
151 }
152 return true;
153
154 error:
155 // Close the pipes, server wont be able to create them otherwise.
156 fNotificationListenPipe.Close();
157 fRequest->Close();
158 fClient->ShutDown(jack_status_t(JackFailure | JackServerError), JACK_SERVER_FAILURE);
159 return false;
160 }
161
162 } // end of namespace
163
164
jack_error
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:92
Jack::JackResult
Result from the server.
Definition: JackRequest.h:129
Jack::JackWinNamedPipeClientChannel::Init
bool Init()
Definition: JackWinNamedPipeClientChannel.cpp:117
jack_log
SERVER_EXPORT void jack_log(const char *fmt,...)
Definition: JackError.cpp:108
Jack::JackClientNotification
ClientNotification.
Definition: JackRequest.h:1636