Jack2 1.9.8

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