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