Jack2  1.9.12
JackSocketClientChannel.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 #include "JackSocketClientChannel.h"
21 #include "JackRequest.h"
22 #include "JackClient.h"
23 #include "JackGlobals.h"
24 #include "JackError.h"
25 
26 namespace Jack
27 {
28 
29 JackSocketClientChannel::JackSocketClientChannel()
30  :JackGenericClientChannel(), fThread(this)
31 {
32  fRequest = new JackClientSocket();
33  fNotificationSocket = NULL;
34 }
35 
36 JackSocketClientChannel::~JackSocketClientChannel()
37 {
38  delete fRequest;
39  delete fNotificationSocket;
40 }
41 
42 int JackSocketClientChannel::Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status)
43 {
44  int result = 0;
45  jack_log("JackSocketClientChannel::Open name = %s", name);
46 
47  // Before any server/client call
48  fClient = client;
49 
50  if (fRequest->Connect(jack_server_dir, server_name, 0) < 0) {
51  jack_error("Cannot connect to server socket");
52  goto error;
53  }
54 
55  // OK so server is there...
56  JackGlobals::fServerRunning = true;
57 
58  // Check name in server
59  ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, true);
60  if (result < 0) {
61  int status1 = *status;
62  if (status1 & JackVersionError) {
63  jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
64  } else {
65  jack_error("Client name = %s conflits with another running client", name);
66  }
67  goto error;
68  }
69 
70  if (fNotificationListenSocket.Bind(jack_client_dir, name_res, 0) < 0) {
71  jack_error("Cannot bind socket");
72  goto error;
73  }
74 
75  return 0;
76 
77 error:
78  fRequest->Close();
79  fNotificationListenSocket.Close();
80  return -1;
81 }
82 
83 void JackSocketClientChannel::Close()
84 {
85  fRequest->Close();
86  fNotificationListenSocket.Close();
87  if (fNotificationSocket) {
88  fNotificationSocket->Close();
89  }
90 }
91 
92 int JackSocketClientChannel::Start()
93 {
94  jack_log("JackSocketClientChannel::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 JackSocketClientChannel::Stop()
107 {
108  jack_log("JackSocketClientChannel::Stop");
109  fThread.Kill();
110 }
111 
113 {
114  jack_log("JackSocketClientChannel::Init");
115  fNotificationSocket = fNotificationListenSocket.Accept();
116 
117  // No more needed
118  fNotificationListenSocket.Close();
119 
120  // Setup context
121  if (!jack_tls_set(JackGlobals::fNotificationThread, this)) {
122  jack_error("Failed to set thread notification key");
123  }
124 
125  if (!fNotificationSocket) {
126  jack_error("JackSocketClientChannel: cannot establish notication socket");
127  return false;
128  } else {
129  return true;
130  }
131 }
132 
133 bool JackSocketClientChannel::Execute()
134 {
136  JackResult res;
137 
138  if (event.Read(fNotificationSocket) < 0) {
139  jack_error("JackSocketClientChannel read fail");
140  goto error;
141  }
142 
143  res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fMessage, event.fValue1, event.fValue2);
144 
145  if (event.fSync) {
146  if (res.Write(fNotificationSocket) < 0) {
147  jack_error("JackSocketClientChannel write fail");
148  goto error;
149  }
150  }
151  return true;
152 
153 error:
154  fNotificationSocket->Close();
155  fClient->ShutDown(jack_status_t(JackFailure | JackServerError), JACK_SERVER_FAILURE);
156  return false;
157 }
158 
159 } // end of namespace
160 
161 
162 
163 
164