Jack2 1.9.6

JackWinSemaphore.cpp

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 #include "JackWinSemaphore.h"
00021 #include "JackConstants.h"
00022 #include "JackTools.h"
00023 #include "JackError.h"
00024 #include <stdio.h>
00025 
00026 namespace Jack
00027 {
00028 
00029 void JackWinSemaphore::BuildName(const char* client_name, const char* server_name, char* res)
00030 {
00031     char ext_client_name[JACK_CLIENT_NAME_SIZE + 1];
00032     JackTools::RewriteName(client_name, ext_client_name);
00033     sprintf(res, "jack_pipe.%s_%s", server_name, ext_client_name);
00034 }
00035 
00036 bool JackWinSemaphore::Signal()
00037 {
00038     BOOL res;
00039     assert(fSemaphore);
00040 
00041     if (fFlush)
00042         return true;
00043 
00044     if (!(res = ReleaseSemaphore(fSemaphore, 1, NULL))) {
00045         jack_error("JackWinSemaphore::Signal name = %s err = %ld", fName, GetLastError());
00046     }
00047 
00048     return res;
00049 }
00050 
00051 bool JackWinSemaphore::SignalAll()
00052 {
00053     BOOL res;
00054     assert(fSemaphore);
00055 
00056     if (fFlush)
00057         return true;
00058 
00059     if (!(res = ReleaseSemaphore(fSemaphore, 1, NULL))) {
00060         jack_error("JackWinSemaphore::SignalAll name = %s err = %ld", fName, GetLastError());
00061     }
00062 
00063     return res;
00064 }
00065 
00066 bool JackWinSemaphore::Wait()
00067 {
00068     DWORD res;
00069 
00070     if ((res = WaitForSingleObject(fSemaphore, INFINITE)) == WAIT_TIMEOUT) {
00071         jack_error("JackWinSemaphore::TimedWait name = %s time_out", fName);
00072     }
00073 
00074     return (res == WAIT_OBJECT_0);
00075 }
00076 
00077 bool JackWinSemaphore::TimedWait(long usec)
00078 {
00079     DWORD res;
00080 
00081     if ((res = WaitForSingleObject(fSemaphore, usec / 1000)) == WAIT_TIMEOUT) {
00082         jack_error("JackWinSemaphore::TimedWait name = %s time_out", fName);
00083     }
00084 
00085     return (res == WAIT_OBJECT_0);
00086 }
00087 
00088 // Client side : get the published semaphore from server
00089 bool JackWinSemaphore::ConnectInput(const char* name, const char* server_name)
00090 {
00091     BuildName(name, server_name, fName);
00092     jack_log("JackWinSemaphore::Connect %s", fName);
00093 
00094     // Temporary...
00095     if (fSemaphore) {
00096         jack_log("Already connected name = %s", name);
00097         return true;
00098     }
00099 
00100     if ((fSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS , FALSE, fName)) == NULL) {
00101         jack_error("Connect: can't check in named event name = %s err = %ld", fName, GetLastError());
00102         return false;
00103     } else {
00104         return true;
00105     }
00106 }
00107 
00108 bool JackWinSemaphore::Connect(const char* name, const char* server_name)
00109 {
00110     return ConnectInput(name, server_name);
00111 }
00112 
00113 bool JackWinSemaphore::ConnectOutput(const char* name, const char* server_name)
00114 {
00115     return ConnectInput(name, server_name);
00116 }
00117 
00118 bool JackWinSemaphore::Disconnect()
00119 {
00120     if (fSemaphore) {
00121         jack_log("JackWinSemaphore::Disconnect %s", fName);
00122         CloseHandle(fSemaphore);
00123         fSemaphore = NULL;
00124         return true;
00125     } else {
00126         return false;
00127     }
00128 }
00129 
00130 bool JackWinSemaphore::Allocate(const char* name, const char* server_name, int value)
00131 {
00132     BuildName(name, server_name, fName);
00133     jack_log("JackWinSemaphore::Allocate name = %s val = %ld", fName, value);
00134 
00135     if ((fSemaphore = CreateSemaphore(NULL, value, 32767, fName)) == NULL) {
00136         jack_error("Allocate: can't check in named semaphore name = %s err = %ld", fName, GetLastError());
00137         return false;
00138     } else if (GetLastError() == ERROR_ALREADY_EXISTS) {
00139         jack_error("Allocate: named semaphore already exist name = %s", fName);
00140         // Try to open it 
00141         fSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, fName);
00142         return (fSemaphore != NULL);
00143     } else {
00144         return true;
00145     }
00146 }
00147 
00148 void JackWinSemaphore::Destroy()
00149 {
00150     if (fSemaphore != NULL) {
00151         jack_log("JackWinSemaphore::Destroy %s", fName);
00152         CloseHandle(fSemaphore);
00153         fSemaphore = NULL;
00154     } else {
00155         jack_error("JackWinSemaphore::Destroy synchro == NULL");
00156     }
00157 }
00158 
00159 
00160 } // end of namespace
00161