1 /* 2 Copyright (C) 2005 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 #ifndef __JackLibGlobals__ 21 #define __JackLibGlobals__ 22 23 #include "JackShmMem.h" 24 #include "JackEngineControl.h" 25 #include "JackGlobals.h" 26 #include "JackPlatformPlug.h" 27 #include "JackGraphManager.h" 28 #include "JackMessageBuffer.h" 29 #include "JackTime.h" 30 #include "JackClient.h" 31 #include "JackError.h" 32 #include <assert.h> 33 #include <signal.h> 34 35 #ifdef WIN32 36 #ifdef __MINGW32__ 37 #include <sys/types.h> 38 typedef _sigset_t sigset_t; 39 #else 40 typedef HANDLE sigset_t; 41 #endif 42 #endif 43 44 namespace Jack 45 { 46 47 class JackClient; 48 49 /*! 50 \brief Global library static structure: singleton kind of pattern. 51 */ 52 53 struct JackLibGlobals 54 { 55 JackShmReadWritePtr<JackGraphManager> fGraphManager; /*! Shared memory Port manager */ 56 JackShmReadWritePtr<JackEngineControl> fEngineControl; /*! Shared engine control */ // transport engine has to be writable 57 JackSynchro fSynchroTable[CLIENT_NUM]; /*! Shared synchro table */ 58 JackMetadata *fMetadata; /*! Shared metadata base */ 59 sigset_t fProcessSignals; 60 61 static int fClientCount; 62 static JackLibGlobals* fGlobals; 63 JackLibGlobalsJackLibGlobals64 JackLibGlobals() 65 { 66 jack_log("JackLibGlobals"); 67 if (!JackMessageBuffer::Create()) { 68 jack_error("Cannot create message buffer"); 69 } 70 fGraphManager = -1; 71 fEngineControl = -1; 72 73 fMetadata = new JackMetadata(false); 74 75 // Filter SIGPIPE to avoid having client get a SIGPIPE when trying to access a died server. 76 #ifdef WIN32 77 // TODO 78 #else 79 sigset_t signals; 80 sigemptyset(&signals); 81 sigaddset(&signals, SIGPIPE); 82 sigprocmask(SIG_BLOCK, &signals, &fProcessSignals); 83 #endif 84 } 85 ~JackLibGlobalsJackLibGlobals86 ~JackLibGlobals() 87 { 88 jack_log("~JackLibGlobals"); 89 for (int i = 0; i < CLIENT_NUM; i++) { 90 fSynchroTable[i].Disconnect(); 91 } 92 JackMessageBuffer::Destroy(); 93 94 delete fMetadata; 95 fMetadata = NULL; 96 97 // Restore old signal mask 98 #ifdef WIN32 99 // TODO 100 #else 101 sigprocmask(SIG_BLOCK, &fProcessSignals, 0); 102 #endif 103 } 104 InitJackLibGlobals105 static void Init() 106 { 107 if (!JackGlobals::fServerRunning && fClientCount > 0) { 108 109 // Cleanup remaining clients 110 jack_error("Jack server was closed but clients are still allocated, cleanup..."); 111 for (int i = 0; i < CLIENT_NUM; i++) { 112 JackClient* client = JackGlobals::fClientTable[i]; 113 if (client) { 114 jack_error("Cleanup client ref = %d", i); 115 client->Close(); 116 delete client; 117 } 118 } 119 120 // Cleanup global context 121 fClientCount = 0; 122 delete fGlobals; 123 fGlobals = NULL; 124 } 125 126 if (fClientCount++ == 0 && !fGlobals) { 127 jack_log("JackLibGlobals Init %x", fGlobals); 128 InitTime(); 129 fGlobals = new JackLibGlobals(); 130 } 131 } 132 DestroyJackLibGlobals133 static void Destroy() 134 { 135 if (--fClientCount == 0 && fGlobals) { 136 jack_log("JackLibGlobals Destroy %x", fGlobals); 137 EndTime(); 138 delete fGlobals; 139 fGlobals = NULL; 140 } 141 } 142 143 }; 144 145 } // end of namespace 146 147 #endif 148 149