00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackServerGlobals.h"
00021 #include "JackTools.h"
00022 #include "shm.h"
00023 #include <getopt.h>
00024 #include <errno.h>
00025 #include <sys/utsname.h>
00026
00027 static char* server_name = NULL;
00028
00029 namespace Jack
00030 {
00031
00032 JackServer* JackServerGlobals::fInstance;
00033 unsigned int JackServerGlobals::fUserCount;
00034 bool (* JackServerGlobals::on_device_acquire)(const char * device_name) = NULL;
00035 void (* JackServerGlobals::on_device_release)(const char * device_name) = NULL;
00036
00037 int JackServerGlobals::Start(const char* server_name,
00038 jack_driver_desc_t* driver_desc,
00039 JSList* driver_params,
00040 int sync,
00041 int temporary,
00042 int time_out_ms,
00043 int rt,
00044 int priority,
00045 int port_max,
00046 int verbose,
00047 jack_timer_type_t clock)
00048 {
00049 jack_log("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld ", sync, time_out_ms, rt, priority, verbose);
00050 new JackServer(sync, temporary, time_out_ms, rt, priority, port_max, verbose, clock, server_name);
00051 int res = fInstance->Open(driver_desc, driver_params);
00052 return (res < 0) ? res : fInstance->Start();
00053 }
00054
00055 void JackServerGlobals::Stop()
00056 {
00057 jack_log("Jackdmp: server close");
00058 fInstance->Stop();
00059 fInstance->Close();
00060 }
00061
00062 void JackServerGlobals::Delete()
00063 {
00064 jack_log("Jackdmp: delete server");
00065 delete fInstance;
00066 fInstance = NULL;
00067 }
00068
00069 bool JackServerGlobals::Init()
00070 {
00071 struct utsname utsname;
00072 int success;
00073 success = uname( &utsname );
00074
00075 int realtime = 0;
00076 int client_timeout = 0;
00077 int realtime_priority;
00078 if( success == 0 && strstr( utsname.version, "ccrma" ) )
00079 realtime_priority = 60;
00080 else
00081 realtime_priority = 20;
00082 int verbose_aux = 0;
00083 int do_mlock = 1;
00084 unsigned int port_max = 128;
00085 int do_unlock = 0;
00086 int temporary = 0;
00087
00088 int opt = 0;
00089 int option_index = 0;
00090 int seen_driver = 0;
00091 char *driver_name = NULL;
00092 char **driver_args = NULL;
00093 JSList* driver_params = NULL;
00094 int driver_nargs = 1;
00095 JSList* drivers = NULL;
00096 int show_version = 0;
00097 int sync = 0;
00098 int rc, i;
00099 int ret;
00100
00101 FILE* fp = 0;
00102 char filename[255];
00103 char buffer[255];
00104 int argc = 0;
00105 char* argv[32];
00106 jack_timer_type_t clock_source = JACK_TIMER_SYSTEM_CLOCK;
00107
00108
00109 if (fUserCount++ == 0) {
00110
00111 jack_log("JackServerGlobals Init");
00112
00113 jack_driver_desc_t* driver_desc;
00114 const char *options = "-ad:P:uvshVRL:STFl:t:mn:p:c:";
00115 static struct option long_options[] = {
00116 { "clock-source", 1, 0, 'c' },
00117 { "driver", 1, 0, 'd' },
00118 { "verbose", 0, 0, 'v' },
00119 { "help", 0, 0, 'h' },
00120 { "port-max", 1, 0, 'p' },
00121 { "no-mlock", 0, 0, 'm' },
00122 { "name", 0, 0, 'n' },
00123 { "unlock", 0, 0, 'u' },
00124 { "realtime", 0, 0, 'R' },
00125 { "realtime-priority", 1, 0, 'P' },
00126 { "timeout", 1, 0, 't' },
00127 { "temporary", 0, 0, 'T' },
00128 { "version", 0, 0, 'V' },
00129 { "silent", 0, 0, 's' },
00130 { "sync", 0, 0, 'S' },
00131 { 0, 0, 0, 0 }
00132 };
00133
00134 snprintf(filename, 255, "%s/.jackdrc", getenv("HOME"));
00135 fp = fopen(filename, "r");
00136
00137 if (!fp) {
00138 fp = fopen("/etc/jackdrc", "r");
00139 }
00140
00141 if (!fp) {
00142 fp = fopen("/etc/jackd.conf", "r");
00143 }
00144
00145 argc = 0;
00146 if (fp) {
00147 ret = fscanf(fp, "%s", buffer);
00148 while (ret != 0 && ret != EOF) {
00149 argv[argc] = (char*)malloc(64);
00150 strcpy(argv[argc], buffer);
00151 ret = fscanf(fp, "%s", buffer);
00152 argc++;
00153 }
00154 fclose(fp);
00155 }
00156
00157
00158
00159
00160
00161
00162
00163 opterr = 0;
00164 optind = 1;
00165
00166 while (!seen_driver &&
00167 (opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) {
00168
00169 switch (opt) {
00170
00171 case 'c':
00172 if (tolower (optarg[0]) == 'h') {
00173 clock_source = JACK_TIMER_HPET;
00174 } else if (tolower (optarg[0]) == 'c') {
00175 clock_source = JACK_TIMER_CYCLE_COUNTER;
00176 } else if (tolower (optarg[0]) == 's') {
00177 clock_source = JACK_TIMER_SYSTEM_CLOCK;
00178 } else {
00179 jack_error("unknown option character %c", optopt);
00180 }
00181 break;
00182
00183 case 'd':
00184 seen_driver = 1;
00185 driver_name = optarg;
00186 break;
00187
00188 case 'v':
00189 verbose_aux = 1;
00190 break;
00191
00192 case 'S':
00193 sync = 1;
00194 break;
00195
00196 case 'n':
00197 server_name = optarg;
00198 break;
00199
00200 case 'm':
00201 do_mlock = 0;
00202 break;
00203
00204 case 'p':
00205 port_max = (unsigned int)atol(optarg);
00206 break;
00207
00208 case 'P':
00209 realtime_priority = atoi(optarg);
00210 break;
00211
00212 case 'R':
00213 realtime = 1;
00214 break;
00215
00216 case 'T':
00217 temporary = 1;
00218 break;
00219
00220 case 't':
00221 client_timeout = atoi(optarg);
00222 break;
00223
00224 case 'u':
00225 do_unlock = 1;
00226 break;
00227
00228 case 'V':
00229 show_version = 1;
00230 break;
00231
00232 default:
00233 jack_error("unknown option character %c", optopt);
00234 break;
00235 }
00236 }
00237
00238 drivers = jack_drivers_load(drivers);
00239 if (!drivers) {
00240 jack_error("jackdmp: no drivers found; exiting");
00241 goto error;
00242 }
00243
00244 driver_desc = jack_find_driver_descriptor(drivers, driver_name);
00245 if (!driver_desc) {
00246 jack_error("jackdmp: unknown driver '%s'", driver_name);
00247 goto error;
00248 }
00249
00250 if (optind < argc) {
00251 driver_nargs = 1 + argc - optind;
00252 } else {
00253 driver_nargs = 1;
00254 }
00255
00256 if (driver_nargs == 0) {
00257 jack_error("No driver specified ... hmm. JACK won't do"
00258 " anything when run like this.");
00259 goto error;
00260 }
00261
00262 driver_args = (char**)malloc(sizeof(char*) * driver_nargs);
00263 driver_args[0] = driver_name;
00264
00265 for (i = 1; i < driver_nargs; i++) {
00266 driver_args[i] = argv[optind++];
00267 }
00268
00269 if (jack_parse_driver_params(driver_desc, driver_nargs, driver_args, &driver_params)) {
00270 goto error;
00271 }
00272
00273 #ifndef WIN32
00274 if (server_name == NULL)
00275 server_name = (char*)JackTools::DefaultServerName();
00276 #endif
00277
00278 rc = jack_register_server(server_name, false);
00279 switch (rc) {
00280 case EEXIST:
00281 jack_error("`%s' server already active", server_name);
00282 goto error;
00283 case ENOSPC:
00284 jack_error("too many servers already active");
00285 goto error;
00286 case ENOMEM:
00287 jack_error("no access to shm registry");
00288 goto error;
00289 default:
00290 jack_info("server `%s' registered", server_name);
00291 }
00292
00293
00294 jack_cleanup_shm();
00295 JackTools::CleanupFiles(server_name);
00296
00297 if (!realtime && client_timeout == 0)
00298 client_timeout = 500;
00299
00300 for (i = 0; i < argc; i++) {
00301 free(argv[i]);
00302 }
00303
00304 int res = Start(server_name, driver_desc, driver_params, sync, temporary, client_timeout, realtime, realtime_priority, port_max, verbose_aux, clock_source);
00305 if (res < 0) {
00306 jack_error("Cannot start server... exit");
00307 Delete();
00308 jack_cleanup_shm();
00309 JackTools::CleanupFiles(server_name);
00310 jack_unregister_server(server_name);
00311 goto error;
00312 }
00313 }
00314
00315 if (driver_params)
00316 jack_free_driver_params(driver_params);
00317 return true;
00318
00319 error:
00320 if (driver_params)
00321 jack_free_driver_params(driver_params);
00322 fUserCount--;
00323 return false;
00324 }
00325
00326 void JackServerGlobals::Destroy()
00327 {
00328 if (--fUserCount == 0) {
00329 jack_log("JackServerGlobals Destroy");
00330 Stop();
00331 Delete();
00332 jack_cleanup_shm();
00333 JackTools::CleanupFiles(server_name);
00334 jack_unregister_server(server_name);
00335 }
00336 }
00337
00338 }
00339
00340