JackServerGlobals.cpp

00001 /*
00002 Copyright (C) 2005 Grame  
00003 
00004 This program is free software; you can redistribute it and/or modify
00005 it under the terms of the GNU General Public License as published by
00006 the Free Software Foundation; either version 2 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 General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017 
00018 */
00019 
00020 #ifdef WIN32 
00021 #pragma warning (disable : 4786)
00022 #endif
00023 
00024 #include "JackServerGlobals.h"
00025 #include "JackError.h"
00026 #include "JackTools.h"
00027 #include "shm.h"
00028 #include <getopt.h>
00029 
00030 #ifndef WIN32
00031         #include <dirent.h>
00032 #endif
00033 
00034 static char* server_name = NULL;
00035 
00036 namespace Jack
00037 {
00038 
00039 unsigned int JackServerGlobals::fClientCount = 0;
00040 JackServer* JackServerGlobals::fServer = NULL;
00041 
00042 int JackServerGlobals::Start(const char* server_name, 
00043                                                                 jack_driver_desc_t* driver_desc, 
00044                                                                 JSList* driver_params, 
00045                                                                 int sync, 
00046                                                                 int temporary, 
00047                                                                 int time_out_ms, 
00048                                                                 int rt, 
00049                                                                 int priority, 
00050                                                                 int loopback, 
00051                                                                 int verbose)
00052 {
00053     JackLog("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld \n", sync, time_out_ms, rt, priority, verbose);
00054         fServer = new JackServer(sync, temporary, time_out_ms, rt, priority, loopback, verbose, server_name);
00055     int res = fServer->Open(driver_desc, driver_params);
00056     return (res < 0) ? res : fServer->Start();
00057 }
00058 
00059 int JackServerGlobals::Stop()
00060 {
00061     fServer->Stop();
00062     fServer->Close();
00063     JackLog("Jackdmp: server close\n");
00064     delete fServer;
00065     JackLog("Jackdmp: delete server\n");
00066     return 0;
00067 }
00068 
00069 int JackServerGlobals::Delete()
00070 {
00071     delete fServer;
00072     JackLog("Jackdmp: delete server\n");
00073     return 0;
00074 }
00075 
00076 bool JackServerGlobals::Init()
00077 {
00078         if (fClientCount++ == 0) {
00079         
00080         JackLog("JackServerGlobals Init\n");
00081                 int realtime = 0;
00082                 int client_timeout = 0; /* msecs; if zero, use period size. */
00083                 int realtime_priority = 10;
00084                 int verbose_aux = 0;
00085                 int do_mlock = 1;
00086                 unsigned int port_max = 128;
00087                 int loopback = 0;
00088                 int do_unlock = 0;
00089                 int temporary = 0;
00090                 
00091                 jack_driver_desc_t* driver_desc;
00092                 const char *options = "-ad:P:uvshVRL:STFl:t:mn:p:";
00093                 static struct option long_options[] = {
00094                                                                                    { "driver", 1, 0, 'd'},
00095                                                                                    { "verbose", 0, 0, 'v' },
00096                                                                                    { "help", 0, 0, 'h' },
00097                                                                                    { "port-max", 1, 0, 'p' },
00098                                                                                    { "no-mlock", 0, 0, 'm' },
00099                                                                                    { "name", 0, 0, 'n' },
00100                                                                                    { "unlock", 0, 0, 'u' },
00101                                                                                    { "realtime", 0, 0, 'R' },
00102                                                                                    { "loopback", 0, 0, 'L' },
00103                                                                                    { "realtime-priority", 1, 0, 'P' },
00104                                                                                    { "timeout", 1, 0, 't' },
00105                                                                                    { "temporary", 0, 0, 'T' },
00106                                                                                    { "version", 0, 0, 'V' },
00107                                                                                    { "silent", 0, 0, 's' },
00108                                                                                    { "sync", 0, 0, 'S' },
00109                                                                                    { 0, 0, 0, 0 }
00110                                                                            };
00111                 int opt = 0;
00112                 int option_index = 0;
00113                 int seen_driver = 0;
00114                 char *driver_name = NULL;
00115                 char **driver_args = NULL;
00116                 JSList* driver_params;
00117                 int driver_nargs = 1;
00118                 JSList* drivers = NULL;
00119                 int show_version = 0;
00120                 int sync = 0;
00121                 int rc, i;
00122                 int ret;
00123                 
00124                 FILE* fp = 0;
00125                 char filename[255];
00126                 char buffer[255];
00127                 int argc = 0;
00128                 char* argv[32];
00129                 
00130                 snprintf(filename, 255, "%s/.jackdrc", getenv("HOME"));
00131                 fp = fopen(filename, "r");
00132 
00133                 if (!fp) {
00134                         fp = fopen("/etc/jackdrc", "r");
00135                 }
00136                 // if still not found, check old config name for backwards compatability 
00137                 if (!fp) {
00138                         fp = fopen("/etc/jackd.conf", "r");
00139                 }
00140 
00141                 argc = 0;
00142                 if (fp) {
00143                         ret = fscanf(fp, "%s", buffer);
00144                         while (ret != 0 && ret != EOF) {
00145                                 argv[argc] = (char*)malloc(64);
00146                                 strcpy(argv[argc], buffer);
00147                                 ret = fscanf(fp, "%s", buffer);
00148                                 argc++;
00149                         }
00150                         fclose(fp);
00151                 }
00152                 
00153                 /*
00154                 For testing
00155                 int argc = 15;
00156                 char* argv[] = {"jackdmp", "-R", "-v", "-d", "coreaudio", "-p", "512", "-d", "~:Aggregate:0", "-r", "48000", "-i", "2", "-o", "2" };
00157                 */
00158 
00159                 opterr = 0;
00160                 optind = 1; // Important : to reset argv parsing
00161                 
00162                 while (!seen_driver &&
00163                                 (opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) {
00164                                 
00165                         switch (opt) {
00166 
00167                                 case 'd':
00168                                         seen_driver = 1;
00169                                         driver_name = optarg;
00170                                         break;
00171 
00172                                 case 'v':
00173                                         verbose_aux = 1;
00174                                         break;
00175 
00176                                 case 'S':
00177                                         sync = 1;
00178                                         break;
00179 
00180                                 case 'n':
00181                                         server_name = optarg;
00182                                         break;
00183 
00184                                 case 'm':
00185                                         do_mlock = 0;
00186                                         break;
00187 
00188                                 case 'p':
00189                                         port_max = (unsigned int)atol(optarg);
00190                                         break;
00191 
00192                                 case 'P':
00193                                         realtime_priority = atoi(optarg);
00194                                         break;
00195 
00196                                 case 'R':
00197                                         realtime = 1;
00198                                         break;
00199 
00200                                 case 'L':
00201                                         loopback = atoi(optarg);
00202                                         break;
00203 
00204                                 case 'T':
00205                                         temporary = 1;
00206                                         break;
00207 
00208                                 case 't':
00209                                         client_timeout = atoi(optarg);
00210                                         break;
00211 
00212                                 case 'u':
00213                                         do_unlock = 1;
00214                                         break;
00215 
00216                                 case 'V':
00217                                         show_version = 1;
00218                                         break;
00219 
00220                                 default:
00221                                         fprintf(stderr, "unknown option character %c\n", optopt);
00222                                         break;
00223                         }
00224                 }
00225                 
00226                 drivers = jack_drivers_load(drivers);
00227                 if (!drivers) {
00228                         fprintf(stderr, "jackdmp: no drivers found; exiting\n");
00229                         goto error;
00230                 }
00231 
00232                 driver_desc = jack_find_driver_descriptor(drivers, driver_name);
00233                 if (!driver_desc) {
00234                         fprintf(stderr, "jackdmp: unknown driver '%s'\n", driver_name);
00235                         goto error;
00236                 }
00237 
00238                 if (optind < argc) {
00239                         driver_nargs = 1 + argc - optind;
00240                 } else {
00241                         driver_nargs = 1;
00242                 }
00243 
00244                 if (driver_nargs == 0) {
00245                         fprintf(stderr, "No driver specified ... hmm. JACK won't do"
00246                                          " anything when run like this.\n");
00247                         goto error;
00248                 }
00249 
00250                 driver_args = (char**)malloc(sizeof(char*) * driver_nargs);
00251                 driver_args[0] = driver_name;
00252 
00253                 for (i = 1; i < driver_nargs; i++) {
00254                         driver_args[i] = argv[optind++];
00255                 }
00256 
00257                 if (jack_parse_driver_params(driver_desc, driver_nargs, driver_args, &driver_params)) {
00258                         goto error;
00259                 }
00260 
00261         #ifndef WIN32
00262                 if (server_name == NULL)
00263                         server_name = (char*)JackTools::DefaultServerName();
00264         #endif
00265 
00266                 rc = jack_register_server(server_name, false);
00267                 switch (rc) {
00268                         case EEXIST:
00269                                 fprintf(stderr, "`%s' server already active\n", server_name);
00270                                 goto error;
00271                         case ENOSPC:
00272                                 fprintf(stderr, "too many servers already active\n");
00273                                 goto error;
00274                         case ENOMEM:
00275                                 fprintf(stderr, "no access to shm registry\n");
00276                                 goto error;
00277                         default:
00278                                 if (jack_verbose)
00279                                         fprintf(stderr, "server `%s' registered\n", server_name);
00280                 }
00281 
00282                 /* clean up shared memory and files from any previous instance of this server name */
00283                 jack_cleanup_shm();
00284         #ifndef WIN32
00285                 JackTools::CleanupFiles(server_name);
00286         #endif
00287 
00288                 if (!realtime && client_timeout == 0)
00289                         client_timeout = 500; /* 0.5 sec; usable when non realtime. */
00290                         
00291                 for (i = 0; i < argc; i++) {
00292                         free(argv[i]);
00293                 }
00294                 
00295                 int res = Start(server_name, driver_desc, driver_params, sync, temporary, client_timeout, realtime, realtime_priority, loopback, verbose_aux);
00296                 if (res < 0) {
00297                         jack_error("Cannot start server... exit");
00298                         Delete();
00299                         jack_cleanup_shm();
00300                 #ifndef WIN32
00301                         JackTools::CleanupFiles(server_name);
00302                 #endif
00303                         jack_unregister_server(server_name);
00304                         goto error;
00305                 }
00306         }
00307         
00308         return true;
00309         
00310 error:
00311         fClientCount--;
00312         return false;
00313 }
00314 
00315 void JackServerGlobals::Destroy()
00316 {
00317     if (--fClientCount == 0) {
00318         JackLog("JackServerGlobals Destroy\n");
00319                 Stop();
00320                 jack_cleanup_shm();
00321         #ifndef WIN32
00322                 JackTools::CleanupFiles(server_name);
00323         #endif
00324                 jack_unregister_server(server_name);
00325     }
00326 }
00327 
00328 } // end of namespace
00329 
00330 

Generated on Thu Feb 14 11:16:02 2008 for Jackdmp by  doxygen 1.5.1