Commit e27f8152 authored by sletz's avatar sletz
Browse files

Rework internal slave driver management, JackServerGlobals now handle same parameters as jackdmp.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4184 0c269be4-1314-0410-8aa9-9f06e86f4224
parent e64c819a
......@@ -34,6 +34,10 @@ Valerio Pilo
Jackdmp changes log
---------------------------
2011-03-13 Stephane Letz <letz@grame.fr>
* Correct JackNetMaster::SetBufferSize.
2011-03-11 Stephane Letz <letz@grame.fr>
* Correct JackNetMaster::SetBufferSize.
......
......@@ -78,15 +78,15 @@ struct jackctl_server
/* int32_t, msecs; if zero, use period size. */
union jackctl_parameter_value client_timeout;
union jackctl_parameter_value default_client_timeout;
/* uint32_t, clock source type */
union jackctl_parameter_value clock_source;
union jackctl_parameter_value default_clock_source;
/* uint32_t, max port number */
union jackctl_parameter_value port_max;
union jackctl_parameter_value default_port_max;
/* bool */
union jackctl_parameter_value replace_registry;
union jackctl_parameter_value default_replace_registry;
......@@ -366,7 +366,7 @@ jackctl_internals_load(
}
while (descriptor_node_ptr != NULL)
{
{
internal_ptr = (struct jackctl_internal *)malloc(sizeof(struct jackctl_internal));
if (internal_ptr == NULL)
{
......@@ -745,7 +745,7 @@ EXPORT jackctl_server_t * jackctl_server_create(
{
goto fail_free_parameters;
}
value.ui = PORT_NUM;
if (jackctl_add_parameter(
&server_ptr->parameters,
......@@ -795,7 +795,7 @@ EXPORT jackctl_server_t * jackctl_server_create(
{
goto fail_free_parameters;
}
/* Allowed to fail */
jackctl_internals_load(server_ptr);
......@@ -882,7 +882,7 @@ jackctl_server_start(
if (!server_ptr->realtime.b && server_ptr->client_timeout.i == 0)
server_ptr->client_timeout.i = 500; /* 0.5 sec; usable when non realtime. */
/* check port max value before allocating server */
if (server_ptr->port_max.ui > PORT_NUM_MAX) {
jack_error("JACK server started with too much ports %d (when port max can be %d)", server_ptr->port_max.ui, PORT_NUM_MAX);
......@@ -896,7 +896,7 @@ jackctl_server_start(
server_ptr->client_timeout.i,
server_ptr->realtime.b,
server_ptr->realtime_priority.i,
server_ptr->port_max.ui,
server_ptr->port_max.ui,
server_ptr->verbose.b,
(jack_timer_type_t)server_ptr->clock_source.ui,
server_ptr->name.str);
......@@ -1179,7 +1179,7 @@ EXPORT bool jackctl_server_load_internal(
{
int status;
if (server_ptr->engine != NULL) {
server_ptr->engine->InternalClientLoad(internal->desc_ptr->name, internal->desc_ptr->name, internal->set_parameters, JackNullOption, &internal->refnum, -1, &status);
server_ptr->engine->InternalClientLoad2(internal->desc_ptr->name, internal->desc_ptr->name, internal->set_parameters, JackNullOption, &internal->refnum, -1, &status);
return (internal->refnum > 0);
} else {
return false;
......@@ -1192,6 +1192,7 @@ EXPORT bool jackctl_server_unload_internal(
{
int status;
if (server_ptr->engine != NULL && internal->refnum > 0) {
// Client object is internally kept in JackEngine, and will be desallocated in InternalClientUnload
return ((server_ptr->engine->GetEngine()->InternalClientUnload(internal->refnum, &status)) == 0);
} else {
return false;
......
......@@ -446,7 +446,7 @@ jack_get_descriptor (JSList * drivers, const char * sofile, const char * symbol)
free(filename);
return NULL;
}
if ((descriptor = so_get_descriptor ()) == NULL) {
jack_error("driver from '%s' returned NULL descriptor", filename);
UnloadDriverModule(dlhandle);
......@@ -467,7 +467,7 @@ jack_get_descriptor (JSList * drivers, const char * sofile, const char * symbol)
/* check it doesn't exist already */
for (node = drivers; node; node = jack_slist_next (node)) {
other_descriptor = (jack_driver_desc_t *) node->data;
if (strcmp(descriptor->name, other_descriptor->name) == 0) {
jack_error("the drivers in '%s' and '%s' both have the name '%s'; using the first",
other_descriptor->file, filename, other_descriptor->name);
......@@ -603,7 +603,7 @@ jack_drivers_load (JSList * drivers) {
}
while ((dir_entry = readdir(dir_stream))) {
/* check the filename is of the right format */
if (strncmp ("jack_", dir_entry->d_name, 5) != 0) {
continue;
......@@ -619,7 +619,7 @@ jack_drivers_load (JSList * drivers) {
}
desc = jack_get_descriptor (drivers, dir_entry->d_name, "driver_get_descriptor");
if (desc) {
driver_list = jack_slist_append (driver_list, desc);
} else {
......@@ -771,9 +771,9 @@ jack_internals_load (JSList * internals) {
#endif
Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver_desc,
Jack::JackLockedEngine* engine,
Jack::JackSynchro* synchro,
Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver_desc,
Jack::JackLockedEngine* engine,
Jack::JackSynchro* synchro,
const JSList* params)
{
#ifdef WIN32
......@@ -783,7 +783,7 @@ Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver
#endif
fHandle = LoadDriverModule (driver_desc->file);
if (fHandle == NULL) {
#ifdef WIN32
if ((errstr = GetLastError ()) != 0) {
......@@ -809,8 +809,14 @@ Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver
jack_error("no initialize function in shared object %s\n", driver_desc->file);
return NULL;
}
fBackend = fInitialize(engine, synchro, params);
return fBackend;
}
JackDriverInfo::~JackDriverInfo()
{
delete fBackend;
if (fHandle)
UnloadDriverModule(fHandle);
}
......@@ -24,14 +24,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "driver_interface.h"
#include "JackControlAPI.h"
#include "JackPlatformPlug.h"
#include "JackDriver.h"
#include "JackSystemDeps.h"
namespace Jack
{
class JackDriverClientInterface;
class JackLockedEngine;
};
typedef jack_driver_desc_t * (*JackDriverDescFunction) ();
typedef Jack::JackDriverClientInterface* (*driverInitialize) (Jack::JackLockedEngine*, Jack::JackSynchro*, const JSList*);
......@@ -39,34 +34,30 @@ class JackDriverInfo
{
private:
driverInitialize fInitialize;
DRIVER_HANDLE fHandle;
Jack::JackDriverClientInterface* fBackend;
public:
JackDriverInfo():fInitialize(NULL),fHandle(NULL)
JackDriverInfo():fInitialize(NULL),fHandle(NULL),fBackend(NULL)
{}
~JackDriverInfo()
{
if (fHandle)
UnloadDriverModule(fHandle);
}
~JackDriverInfo();
Jack::JackDriverClientInterface* Open(jack_driver_desc_t* driver_desc, Jack::JackLockedEngine*, Jack::JackSynchro*, const JSList*);
Jack::JackDriverClientInterface* GetBackend()
{
return fBackend;
}
};
jack_driver_desc_t * jack_find_driver_descriptor (JSList * drivers, const char * name);
jack_driver_desc_t * jack_find_driver_descriptor(JSList * drivers, const char * name);
JSList * jack_drivers_load (JSList * drivers);
JSList * jack_internals_load (JSList * internals);
JSList * jack_drivers_load(JSList * drivers);
JSList * jack_internals_load(JSList * internals);
EXPORT int jackctl_parse_driver_params (jackctl_driver * driver_ptr, int argc, char* argv[]);
EXPORT void jack_free_driver_params(JSList * param_ptr);
......
......@@ -136,7 +136,7 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface
void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result)
{
*result = fServer->InternalClientLoad(client_name, so_name, objet_data, options, int_ref, uuid, status);
*result = fServer->InternalClientLoad1(client_name, so_name, objet_data, options, int_ref, uuid, status);
}
void InternalClientUnload(int refnum, int int_ref, int* status, int* result)
......
......@@ -61,7 +61,6 @@ JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int prio
JackServer::~JackServer()
{
JackGraphManager::Destroy(fGraphManager);
delete fAudioDriver;
delete fDriverInfo;
delete fFreewheelDriver;
delete fEngine;
......@@ -136,14 +135,14 @@ int JackServer::Close()
return 0;
}
int JackServer::InternalClientLoad(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status)
int JackServer::InternalClientLoad1(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status)
{
JackLoadableInternalClient* client = new JackLoadableInternalClient1(JackServerGlobals::fInstance, GetSynchroTable(), objet_data);
assert(client);
return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status);
}
int JackServer::InternalClientLoad(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status)
int JackServer::InternalClientLoad2(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status)
{
JackLoadableInternalClient* client = new JackLoadableInternalClient2(JackServerGlobals::fInstance, GetSynchroTable(), parameters);
assert(client);
......@@ -154,6 +153,8 @@ int JackServer::InternalClientLoadAux(JackLoadableInternalClient* client, const
{
// Clear status
*status = 0;
// Client object is internally kept in JackEngine
if ((client->Init(so_name) < 0) || (client->Open(JACK_DEFAULT_SERVER_NAME, client_name, uuid, (jack_options_t)options, (jack_status_t*)status) < 0)) {
delete client;
int my_status1 = *status | JackFailure;
......@@ -338,7 +339,6 @@ int JackServer::SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_par
}
// Delete old master
delete fAudioDriver;
delete fDriverInfo;
// Activate master
......
......@@ -57,7 +57,7 @@ class SERVER_EXPORT JackServer
JackConnectionManager fConnectionState;
JackSynchro fSynchroTable[CLIENT_NUM];
bool fFreewheel;
int InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, int uuid, int* status);
public:
......@@ -77,19 +77,19 @@ class SERVER_EXPORT JackServer
// Command thread : API
int SetBufferSize(jack_nframes_t buffer_size);
int SetFreewheel(bool onoff);
int InternalClientLoad(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status);
int InternalClientLoad(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status);
int InternalClientLoad1(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status);
int InternalClientLoad2(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status);
void ClientKill(int refnum);
// Transport management
int ReleaseTimebase(int refnum);
int SetTimebaseCallback(int refnum, int conditional);
// Backend management
JackDriverInfo* AddSlave(jack_driver_desc_t* driver_desc, JSList* driver_params);
void RemoveSlave(JackDriverInfo* info);
int SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_params);
// Object access
JackLockedEngine* GetEngine();
JackEngineControl* GetEngineControl();
......
......@@ -63,7 +63,7 @@ jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t optio
}
jack_log("jack_client_new %s", client_name);
if (status == NULL) /* no status from caller? */
status = &my_status; /* use local status word */
*status = (jack_status_t)0;
......@@ -77,13 +77,13 @@ jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t optio
/* parse variable arguments */
jack_varargs_init(&va);
if (!JackServerGlobals::Init()) { // jack server initialisation
int my_status1 = (JackFailure | JackServerError);
*status = (jack_status_t)my_status1;
return NULL;
}
if (JACK_DEBUG) {
client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode
} else {
......@@ -114,7 +114,7 @@ jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t opti
}
jack_log("jack_client_open %s", client_name);
if (status == NULL) /* no status from caller? */
status = &my_status; /* use local status word */
*status = (jack_status_t)0;
......@@ -128,13 +128,13 @@ jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t opti
/* parse variable arguments */
jack_varargs_parse(options, ap, &va);
if (!JackServerGlobals::Init()) { // jack server initialisation
int my_status1 = (JackFailure | JackServerError);
*status = (jack_status_t)my_status1;
return NULL;
}
if (JACK_DEBUG) {
client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode
} else {
......@@ -180,7 +180,7 @@ EXPORT int jack_client_close(jack_client_t* ext_client)
{
#ifdef __CLIENTDEBUG__
JackGlobals::CheckContext("jack_client_close");
#endif
#endif
assert(JackGlobals::fOpenMutex);
JackGlobals::fOpenMutex->Lock();
int res = -1;
......@@ -200,7 +200,7 @@ EXPORT int jack_client_close(jack_client_t* ext_client)
EXPORT int jack_get_client_pid(const char *name)
{
return (JackServerGlobals::fInstance != NULL)
return (JackServerGlobals::fInstance != NULL)
? JackServerGlobals::fInstance->GetEngine()->GetClientPID(name)
: 0;
}
......
......@@ -18,6 +18,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "JackServerGlobals.h"
#include "JackLockedEngine.h"
#include "JackTools.h"
#include "shm.h"
#include <getopt.h>
......@@ -31,6 +32,8 @@ namespace Jack
JackServer* JackServerGlobals::fInstance;
unsigned int JackServerGlobals::fUserCount;
int JackServerGlobals::fRTNotificationSocket;
std::map<std::string, JackDriverInfo*> JackServerGlobals::fSlavesList;
std::map<std::string, int> JackServerGlobals::fInternalsList;
bool (* JackServerGlobals::on_device_acquire)(const char * device_name) = NULL;
void (* JackServerGlobals::on_device_release)(const char * device_name) = NULL;
......@@ -63,6 +66,30 @@ void JackServerGlobals::Stop()
void JackServerGlobals::Delete()
{
jack_log("Jackdmp: delete server");
// Slave drivers
std::map<std::string, JackDriverInfo*>::iterator it1;
for (it1 = fSlavesList.begin(); it1 != fSlavesList.end(); it1++) {
JackDriverInfo* info = (*it1).second;
if (info) {
fInstance->RemoveSlave((info));
delete (info);
}
}
fSlavesList.clear();
// Internal clients
std::map<std::string, int> ::iterator it2;
for (it2 = fInternalsList.begin(); it2 != fInternalsList.end(); it2++) {
int status;
int refnum = (*it2).second;
if (refnum > 0) {
// Client object is internally kept in JackEngine, and will be desallocated in InternalClientUnload
fInstance->GetEngine()->InternalClientUnload(refnum, &status);
}
}
fInternalsList.clear();
delete fInstance;
fInstance = NULL;
}
......@@ -80,49 +107,62 @@ bool JackServerGlobals::Init()
int opt = 0;
int option_index = 0;
int seen_driver = 0;
char *driver_name = NULL;
char **driver_args = NULL;
JSList* driver_params = NULL;
char *master_driver_name = NULL;
char **master_driver_args = NULL;
JSList* master_driver_params = NULL;
jack_driver_desc_t* driver_desc;
jack_timer_type_t clock_source = JACK_TIMER_SYSTEM_CLOCK;
int driver_nargs = 1;
JSList* drivers = NULL;
int show_version = 0;
int loopback = 0;
int sync = 0;
int rc, i;
int ret;
int replace_registry = 0;
FILE* fp = 0;
char filename[255];
char buffer[255];
int argc = 0;
char* argv[32];
jack_timer_type_t clock_source = JACK_TIMER_SYSTEM_CLOCK;
// First user starts the server
if (fUserCount++ == 0) {
jack_log("JackServerGlobals Init");
jack_driver_desc_t* driver_desc;
const char *options = "-ad:P:uvshVRL:STFl:t:mn:p:c:";
static struct option long_options[] = {
{ "clock-source", 1, 0, 'c' },
{ "driver", 1, 0, 'd' },
{ "verbose", 0, 0, 'v' },
{ "help", 0, 0, 'h' },
{ "port-max", 1, 0, 'p' },
{ "no-mlock", 0, 0, 'm' },
{ "name", 0, 0, 'n' },
{ "unlock", 0, 0, 'u' },
{ "realtime", 0, 0, 'R' },
{ "realtime-priority", 1, 0, 'P' },
{ "timeout", 1, 0, 't' },
{ "temporary", 0, 0, 'T' },
{ "version", 0, 0, 'V' },
{ "silent", 0, 0, 's' },
{ "sync", 0, 0, 'S' },
{ 0, 0, 0, 0 }
};
const char *options = "-d:X:I:P:uvshVrRL:STFl:t:mn:p:"
#ifdef __linux__
"c:"
#endif
;
struct option long_options[] = {
#ifdef __linux__
{ "clock-source", 1, 0, 'c' },
#endif
{ "loopback-driver", 1, 0, 'L' },
{ "audio-driver", 1, 0, 'd' },
{ "midi-driver", 1, 0, 'X' },
{ "internal-client", 1, 0, 'I' },
{ "verbose", 0, 0, 'v' },
{ "help", 0, 0, 'h' },
{ "port-max", 1, 0, 'p' },
{ "no-mlock", 0, 0, 'm' },
{ "name", 1, 0, 'n' },
{ "unlock", 0, 0, 'u' },
{ "realtime", 0, 0, 'R' },
{ "no-realtime", 0, 0, 'r' },
{ "replace-registry", 0, &replace_registry, 0 },
{ "loopback", 0, 0, 'L' },
{ "realtime-priority", 1, 0, 'P' },
{ "timeout", 1, 0, 't' },
{ "temporary", 0, 0, 'T' },
{ "version", 0, 0, 'V' },
{ "silent", 0, 0, 's' },
{ "sync", 0, 0, 'S' },
{ 0, 0, 0, 0 }
};
snprintf(filename, 255, "%s/.jackdrc", getenv("HOME"));
fp = fopen(filename, "r");
......@@ -156,7 +196,7 @@ bool JackServerGlobals::Init()
opterr = 0;
optind = 1; // Important : to reset argv parsing
while (!seen_driver &&
while (!master_driver_name &&
(opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) {
switch (opt) {
......@@ -174,34 +214,53 @@ bool JackServerGlobals::Init()
break;
case 'd':
seen_driver = 1;
driver_name = optarg;
master_driver_name = optarg;
break;
case 'v':
verbose_aux = 1;
case 'L':
loopback = atoi(optarg);
break;
case 'S':
sync = 1;
case 'X':
fSlavesList[optarg] = NULL;
break;
case 'n':
server_name = optarg;
case 'I':
fInternalsList[optarg] = -1;
break;
case 'p':
port_max = (unsigned int)atol(optarg);
break;
case 'm':
do_mlock = 0;
break;
case 'p':
port_max = (unsigned int)atol(optarg);
case 'u':
do_unlock = 1;
break;
case 'v':
verbose_aux = 1;
break;
case 'S':
sync = 1;
break;
case 'n':
server_name = optarg;
break;
case 'P':
realtime_priority = atoi(optarg);
break;
case 'r':
realtime = 0;
break;
case 'R':
realtime = 1;
break;
......@@ -214,14 +273,6 @@ bool JackServerGlobals::Init()
client_timeout = atoi(optarg);
break;
case 'u':
do_unlock = 1;
break;
case 'V':
show_version = 1;
break;
default:
jack_error("unknown option character %c", optopt);
break;
......@@ -234,9 +285,9 @@ bool JackServerGlobals::Init()
goto error;
}
driver_desc = jack_find_driver_descriptor(drivers, driver_name);
driver_desc = jack_find_driver_descriptor(drivers, master_driver_name);
if (!driver_desc) {
jack_error("jackdmp: unknown driver '%s'", driver_name);
jack_error("jackdmp: unknown master driver '%s'", master_driver_name);
goto error;
}
......@@ -252,14 +303,14 @@ bool JackServerGlobals::Init()
goto error;
}
driver_args = (char**)malloc(sizeof(char*) * driver_nargs);
driver_args[0] = driver_name;
master_driver_args = (char**)malloc(sizeof(char*) * driver_nargs);
master_driver_args[0] = master_driver_name;