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