Jack2 1.9.10
|
00001 /* 00002 Copyright (C) 2004-2008 Grame 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as published by 00006 the Free Software Foundation; either version 2.1 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 00018 */ 00019 00020 00021 #include "JackWinNamedPipeClientChannel.h" 00022 #include "JackRequest.h" 00023 #include "JackClient.h" 00024 #include "JackGlobals.h" 00025 #include "JackError.h" 00026 00027 namespace Jack 00028 { 00029 00030 JackWinNamedPipeClientChannel::JackWinNamedPipeClientChannel() 00031 :JackGenericClientChannel(),fThread(this) 00032 { 00033 fRequest = new JackWinNamedPipeClient(); 00034 } 00035 00036 JackWinNamedPipeClientChannel::~JackWinNamedPipeClientChannel() 00037 { 00038 delete fRequest; 00039 } 00040 00041 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) 00042 { 00043 int result = 0; 00044 jack_log("JackWinNamedPipeClientChannel::Open name = %s", name); 00045 00046 /* 00047 16/08/07: was called before doing "fRequest->Connect" .... still necessary? 00048 if (fNotificationListenPipe.Bind(jack_client_dir, name, 0) < 0) { 00049 jack_error("Cannot bind pipe"); 00050 goto error; 00051 } 00052 */ 00053 00054 // Before any server/client call 00055 fClient = client; 00056 00057 if (fRequest->Connect(jack_server_dir, server_name, 0) < 0) { 00058 jack_error("Cannot connect to server pipe"); 00059 goto error; 00060 } 00061 00062 // OK so server is there... 00063 JackGlobals::fServerRunning = true; 00064 00065 // Check name in server 00066 ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, true); 00067 if (result < 0) { 00068 int status1 = *status; 00069 if (status1 & JackVersionError) { 00070 jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION); 00071 } else { 00072 jack_error("Client name = %s conflits with another running client", name); 00073 } 00074 } 00075 00076 if (fNotificationListenPipe.Bind(jack_client_dir, name_res, 0) < 0) { 00077 jack_error("Cannot bind pipe"); 00078 goto error; 00079 } 00080 00081 return 0; 00082 00083 error: 00084 fRequest->Close(); 00085 fNotificationListenPipe.Close(); 00086 return -1; 00087 } 00088 00089 void JackWinNamedPipeClientChannel::Close() 00090 { 00091 fRequest->Close(); 00092 fNotificationListenPipe.Close(); 00093 // Here the thread will correctly stop when the pipe are closed 00094 fThread.Stop(); 00095 } 00096 00097 int JackWinNamedPipeClientChannel::Start() 00098 { 00099 jack_log("JackWinNamedPipeClientChannel::Start"); 00100 /* 00101 To be sure notification thread is started before ClientOpen is called. 00102 */ 00103 if (fThread.StartSync() != 0) { 00104 jack_error("Cannot start Jack client listener"); 00105 return -1; 00106 } else { 00107 return 0; 00108 } 00109 } 00110 00111 void JackWinNamedPipeClientChannel::Stop() 00112 { 00113 jack_log("JackWinNamedPipeClientChannel::Stop"); 00114 fThread.Kill(); // Unsafe on WIN32... TODO : solve WIN32 thread Kill issue 00115 } 00116 00117 bool JackWinNamedPipeClientChannel::Init() 00118 { 00119 jack_log("JackWinNamedPipeClientChannel::Init"); 00120 00121 // Setup context 00122 if (!jack_tls_set(JackGlobals::fNotificationThread, this)) { 00123 jack_error("Failed to set thread notification key"); 00124 } 00125 00126 if (!fNotificationListenPipe.Accept()) { 00127 jack_error("JackWinNamedPipeClientChannel: cannot establish notification pipe"); 00128 return false; 00129 } else { 00130 return true; 00131 } 00132 } 00133 00134 bool JackWinNamedPipeClientChannel::Execute() 00135 { 00136 JackClientNotification event; 00137 JackResult res; 00138 00139 if (event.Read(&fNotificationListenPipe) < 0) { 00140 jack_error("JackWinNamedPipeClientChannel read fail"); 00141 goto error; 00142 } 00143 00144 res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fMessage, event.fValue1, event.fValue2); 00145 00146 if (event.fSync) { 00147 if (res.Write(&fNotificationListenPipe) < 0) { 00148 jack_error("JackWinNamedPipeClientChannel write fail"); 00149 goto error; 00150 } 00151 } 00152 return true; 00153 00154 error: 00155 // Close the pipes, server wont be able to create them otherwise. 00156 fNotificationListenPipe.Close(); 00157 fRequest->Close(); 00158 fClient->ShutDown(jack_status_t(JackFailure | JackServerError), JACK_SERVER_FAILURE); 00159 return false; 00160 } 00161 00162 } // end of namespace 00163 00164