Browse Source

Automatic server launch

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@1516 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.64
sletz 18 years ago
parent
commit
e8fcf23258
14 changed files with 108 additions and 190 deletions
  1. +4
    -0
      ChangeLog
  2. +0
    -160
      common/JackAPI.cpp
  3. +5
    -0
      common/JackChannel.h
  4. +9
    -2
      common/JackLibAPI.cpp
  5. +1
    -0
      common/JackLibGlobals.h
  6. +9
    -1
      common/JackServerAPI.cpp
  7. +8
    -9
      common/JackServerGlobals.cpp
  8. +14
    -0
      common/JackSocketClientChannel.cpp
  9. +2
    -0
      common/JackSocketClientChannel.h
  10. +13
    -0
      macosx/JackMachClientChannel.cpp
  11. +3
    -1
      macosx/JackMachClientChannel.h
  12. +8
    -0
      macosx/Jackdmp.xcodeproj/project.pbxproj
  13. +30
    -17
      windows/JackWinNamedPipeClientChannel.cpp
  14. +2
    -0
      windows/JackWinNamedPipeClientChannel.h

+ 4
- 0
ChangeLog View File

@@ -4,6 +4,10 @@

2007-08-21 Stephane Letz <letz@grame.fr>
* Automatic server launch.

2007-08-20 Stephane Letz <letz@grame.fr>
* Add "systemic" latencies management in CoreAudio driver.
2007-08-16 Stephane Letz <letz@grame.fr>


+ 0
- 160
common/JackAPI.cpp View File

@@ -1202,7 +1202,6 @@ EXPORT int jack_port_name_size(void)
}

// transport.h

EXPORT int jack_release_timebase(jack_client_t* ext_client)
{
#ifdef __CLIENTDEBUG__
@@ -1342,7 +1341,6 @@ EXPORT void jack_transport_stop(jack_client_t* ext_client)
}

// deprecated

EXPORT void jack_get_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo)
{
jack_error("jack_get_transport_info: deprecated");
@@ -1358,7 +1356,6 @@ EXPORT void jack_set_transport_info(jack_client_t* ext_client, jack_transport_in
}

// statistics.h

EXPORT float jack_get_max_delayed_usecs(jack_client_t* ext_client)
{
#ifdef __CLIENTDEBUG__
@@ -1386,7 +1383,6 @@ EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client)
}

// thread.h

EXPORT int jack_acquire_real_time_scheduling(pthread_t thread, int priority)
{
#ifdef __APPLE__
@@ -1426,7 +1422,6 @@ EXPORT int jack_drop_real_time_scheduling(pthread_t thread)
}

// intclient.h

EXPORT char* jack_get_internal_client_name(jack_client_t* ext_client, jack_intclient_t intclient)
{
JackLog("jack_get_internal_client_name: not yet implemented\n");
@@ -1451,158 +1446,3 @@ EXPORT jack_status_t jack_internal_client_unload(jack_client_t* ext_client, jack
return JackFailure;
}

// Automatic jack server launch

#ifndef WIN32

#define JACK_LOCATION
#define JACK_DEFAULT_DRIVER

/* Exec the JACK server in this process. Does not return. */
static void start_server_aux(const char *server_name)
{
FILE* fp = 0;
char filename[255];
char arguments[255];
char buffer[255];
char* command = 0;
size_t pos = 0;
size_t result = 0;
char** argv = 0;
int i = 0;
int good = 0;
int ret;
snprintf(filename, 255, "%s/.jackdrc", getenv("HOME"));
fp = fopen(filename, "r");

if (!fp) {
fp = fopen("/etc/jackdrc", "r");
}
/* if still not found, check old config name for backwards compatability */
if (!fp) {
fp = fopen("/etc/jackd.conf", "r");
}

if (fp) {
arguments[0] = '\0';
ret = fscanf(fp, "%s", buffer);
while(ret != 0 && ret != EOF) {
strcat(arguments, buffer);
strcat(arguments, " ");
ret = fscanf(fp, "%s", buffer);
}
if (strlen(arguments) > 0) {
good = 1;
}
}

if (!good) {
command = JACK_LOCATION "/jackdmp";
strncpy(arguments, JACK_LOCATION "/jackdmp -T -d "JACK_DEFAULT_DRIVER, 255);
} else {
result = strcspn(arguments, " ");
command = (char *) malloc(result+1);
strncpy(command, arguments, result);
command[result] = '\0';
}

argv = (char **)malloc(255);
while (1) {
/* insert -T and -nserver_name in front of arguments */
if (i == 1) {
argv[i] = (char *) malloc(strlen ("-T") + 1);
strcpy (argv[i++], "-T");
if (server_name) {
size_t optlen = strlen ("-n");
char* buf = (char*)malloc(optlen + strlen (server_name) + 1);
strcpy(buf, "-n");
strcpy(buf+optlen, server_name);
argv[i++] = buf;
}
}

result = strcspn(arguments + pos, " ");
if (result == 0) {
break;
}
argv[i] = (char*)malloc(result + 1);
strncpy(argv[i], arguments+pos, result);
argv[i][result] = '\0';
pos += result + 1;
++i;
}
argv[i] = 0;
execv(command, argv);

/* If execv() succeeds, it does not return. There's no point
* in calling jack_error() here in the child process. */
fprintf(stderr, "exec of JACK server (command = \"%s\") failed: %s\n", command, strerror(errno));
}

static int start_server(const char *server_name, jack_options_t options)
{
if ((options & JackNoStartServer) || getenv("JACK_NO_START_SERVER")) {
return 1;
}

/* The double fork() forces the server to become a child of
* init, which will always clean up zombie process state on
* termination. This even works in cases where the server
* terminates but this client does not.
*
* Since fork() is usually implemented using copy-on-write
* virtual memory tricks, the overhead of the second fork() is
* probably relatively small.
*/
switch (fork()) {
case 0: /* child process */
switch (fork()) {
case 0: /* grandchild process */
start_server_aux(server_name);
_exit(99); /* exec failed */
case -1:
_exit(98);
default:
_exit(0);
}
case -1: /* fork() error */
return 1; /* failed to start server */
}

/* only the original parent process goes here */
return 0; /* (probably) successful */
}

int server_connect(char* name)
{
return -1;
}

int try_start_server(jack_varargs_t* va, jack_options_t options, jack_status_t* status)
{
if (server_connect(va->server_name) < 0) {
int trys;
if (start_server(va->server_name, options)) {
int my_status1 = *status | JackFailure | JackServerFailed;
*status = (jack_status_t)my_status1;
return -1;
}
trys = 5;
do {
sleep(1);
if (--trys < 0) {
int my_status1 = *status | JackFailure | JackServerFailed;
*status = (jack_status_t)my_status1;
return -1;
}
} while (server_connect(va->server_name) < 0);
int my_status1 = *status | JackServerStarted;
*status = (jack_status_t)my_status1;
}
return 0;
}

#endif

+ 5
- 0
common/JackChannel.h View File

@@ -67,6 +67,11 @@ class JackClientChannelInterface
virtual void Stop()
{}
virtual int ServerCheck(const char* server_name)
{
return -1;
}
virtual void ClientCheck(const char* name, char* name_res, int options, int* status, int* result)
{}
virtual void ClientOpen(const char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result)


+ 9
- 2
common/JackLibAPI.cpp View File

@@ -21,10 +21,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "JackDebugClient.h"
#include "JackLibClient.h"
#include "JackChannel.h"
#include "JackGraphManager.h"
#include "JackLibGlobals.h"
#include "JackGlobals.h"
#include "varargs.h"
#include "JackServerLaunch.h"

using namespace Jack;

@@ -86,6 +85,14 @@ static jack_client_t* jack_client_open_aux(const char* client_name, jack_options
}

JackLibGlobals::Init(); // jack library initialisation
#ifndef WIN32
if (try_start_server(&va, options, status)) {
jack_error("jack server is not running or cannot be started");
JackLibGlobals::Destroy(); // jack library destruction
return 0;
}
#endif

#ifdef __CLIENTDEBUG__
JackClient* client = new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode


+ 1
- 0
common/JackLibGlobals.h View File

@@ -27,6 +27,7 @@ This program is free software; you can redistribute it and/or modify
#include <map>
#endif
#include "JackGlobals.h"
#include "JackGraphManager.h"
#include "JackTime.h"
#include <assert.h>



+ 9
- 1
common/JackServerAPI.cpp View File

@@ -28,7 +28,7 @@ This program is free software; you can redistribute it and/or modify
#include "JackDebugClient.h"
#include "JackServerGlobals.h"
#include "JackError.h"
#include "varargs.h"
#include "JackServerLaunch.h"

/*
TODO:
@@ -141,6 +141,14 @@ EXPORT jack_client_t* jack_client_open(const char* client_name, jack_options_t o

JackServerGlobals::Init(); // jack server initialisation

#ifndef WIN32
if (try_start_server(&va, options, status)) {
jack_error("jack server is not running or cannot be started");
JackServerGlobals::Destroy(); // jack library destruction
return 0;
}
#endif

#ifdef __CLIENTDEBUG__
JackClient* client = new JackDebugClient(new JackInternalClient(JackServer::fInstance, GetSynchroTable())); // Debug mode
#else


+ 8
- 9
common/JackServerGlobals.cpp View File

@@ -16,10 +16,10 @@ This program is free software; you can redistribute it and/or modify
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/
#ifdef WIN32
#pragma warning (disable : 4786)
#endif
#ifdef WIN32
#pragma warning (disable : 4786)
#endif

#include "JackServerGlobals.h"
#include "JackError.h"
@@ -181,7 +181,6 @@ int JackServerGlobals::JackDelete()
}

// Temporary : to test

JackServerGlobals::JackServerGlobals()
{
jack_driver_desc_t* driver_desc;
@@ -323,24 +322,24 @@ JackServerGlobals::JackServerGlobals()
return ;
}

driver_args = (char **) malloc (sizeof (char *) * driver_nargs);
driver_args = (char**) malloc(sizeof(char *) * driver_nargs);
driver_args[0] = driver_name;

for (i = 1; i < driver_nargs; i++) {
driver_args[i] = argv[optind++];
}

if (jack_parse_driver_params (driver_desc, driver_nargs,
if (jack_parse_driver_params(driver_desc, driver_nargs,
driver_args, &driver_params)) {
return ;
}

#ifndef WIN32
if (server_name == NULL)
server_name = jack_default_server_name ();
server_name = jack_default_server_name();
#endif

rc = jack_register_server (server_name);
rc = jack_register_server(server_name);

/* clean up shared memory and files from any previous
* instance of this server name */


+ 14
- 0
common/JackSocketClientChannel.cpp View File

@@ -38,6 +38,20 @@ JackSocketClientChannel::~JackSocketClientChannel()
delete fNotificationSocket;
}

int JackSocketClientChannel::ServerCheck(const char* server_name)
{
JackLog("JackSocketClientChannel::ServerCheck = %s\n", server_name);
// Connect to server
if (fRequestSocket.Connect(jack_server_dir, 0) < 0) {
jack_error("Cannot connect to server socket");
fRequestSocket.Close();
return -1;
} else {
return 0;
}
}

int JackSocketClientChannel::Open(const char* name, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status)
{
int result = 0;


+ 2
- 0
common/JackSocketClientChannel.h View File

@@ -56,6 +56,8 @@ class JackSocketClientChannel : public JackClientChannelInterface, public JackRu

int Start();
void Stop();
int ServerCheck(const char* server_name);

void ClientCheck(const char* name, char* name_res, int options, int* status, int* result);
void ClientOpen(const char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result);


+ 13
- 0
macosx/JackMachClientChannel.cpp View File

@@ -41,6 +41,19 @@ JackMachClientChannel::~JackMachClientChannel()

// Server <===> client

int JackMachClientChannel::ServerCheck(const char* server_name)
{
JackLog("JackMachClientChannel::ServerCheck = %s\n", server_name);
// Connect to server
if (!fServerPort.ConnectPort(jack_server_entry)) {
jack_error("Cannot connect to server Mach port");
return -1;
} else {
return 0;
}
}

int JackMachClientChannel::Open(const char* name, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status)
{
JackLog("JackMachClientChannel::Open name = %s\n", name);


+ 3
- 1
macosx/JackMachClientChannel.h View File

@@ -53,7 +53,9 @@ class JackMachClientChannel : public JackClientChannelInterface, public JackRunn

int Start();
void Stop();

int ServerCheck(const char* server_name);
void ClientCheck(const char* name, char* name_res, int options, int* status, int* result);
void ClientOpen(const char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result);
void ClientClose(int refnum, int* result);


+ 8
- 0
macosx/Jackdmp.xcodeproj/project.pbxproj View File

@@ -43,6 +43,9 @@

/* Begin PBXBuildFile section */
4B3F49080AD8503300491C6E /* jack_cpu.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3F49070AD8503300491C6E /* jack_cpu.c */; };
4B44FAE60C7598370033A72C /* JackServerLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B44FAE50C7598370033A72C /* JackServerLaunch.cpp */; };
4B44FAE70C7598370033A72C /* JackServerLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B44FAE50C7598370033A72C /* JackServerLaunch.cpp */; };
4B44FAE80C7598370033A72C /* JackServerLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B44FAE50C7598370033A72C /* JackServerLaunch.cpp */; };
4B60CE490AAABA31004956AA /* connect.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B60CE480AAABA31004956AA /* connect.c */; };
4B60CE4A0AAABA31004956AA /* connect.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B60CE480AAABA31004956AA /* connect.c */; };
4B699BAA097D421600A18468 /* Jackdmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2250834F06A00C94B91 /* Jackdmp.cpp */; };
@@ -442,6 +445,7 @@
4B395C9706AEF53800923527 /* JackCoreAudioDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JackCoreAudioDriver.h; sourceTree = SOURCE_ROOT; };
4B3F49070AD8503300491C6E /* jack_cpu.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = jack_cpu.c; path = ../tests/jack_cpu.c; sourceTree = SOURCE_ROOT; };
4B4259E5076B635E00C1ECE1 /* JackMacEngineRPC.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMacEngineRPC.cpp; sourceTree = SOURCE_ROOT; };
4B44FAE50C7598370033A72C /* JackServerLaunch.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackServerLaunch.cpp; path = ../common/JackServerLaunch.cpp; sourceTree = SOURCE_ROOT; };
4B464301076CAC7700E5077C /* Jack-Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = "Jack-Info.plist"; sourceTree = SOURCE_ROOT; };
4B56880F08B5C8620022B32D /* JackFifo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackFifo.cpp; path = ../common/JackFifo.cpp; sourceTree = SOURCE_ROOT; };
4B56881008B5C8620022B32D /* JackFifo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackFifo.h; path = ../common/JackFifo.h; sourceTree = SOURCE_ROOT; };
@@ -1056,6 +1060,7 @@
4B98AE000931D30C0091932A /* JackDebugClient.cpp */,
4BF8D1E90834EF7500C94B91 /* JackAPI.cpp */,
4BE50F650B01E96200C05E63 /* JackAPIWrapper.cpp */,
4B44FAE50C7598370033A72C /* JackServerLaunch.cpp */,
4BD56D75079687EB006D44F9 /* Internal */,
4BD56D73079687AD006D44F9 /* External */,
4BA550F905E241D900569492 /* Library */,
@@ -2010,6 +2015,7 @@
buildActionMask = 2147483647;
files = (
4B699BAA097D421600A18468 /* Jackdmp.cpp in Sources */,
4B44FAE60C7598370033A72C /* JackServerLaunch.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2046,6 +2052,7 @@
4B699C3F097D421600A18468 /* ringbuffer.c in Sources */,
4B699C40097D421600A18468 /* JackDebugClient.cpp in Sources */,
4BD4B4E409BACEF300750C0F /* JackTransportEngine.cpp in Sources */,
4B44FAE70C7598370033A72C /* JackServerLaunch.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2096,6 +2103,7 @@
4BD4B4D909BACD9600750C0F /* JackTransportEngine.cpp in Sources */,
4BC216850A444BAD00BDA09F /* JackServerAPI.cpp in Sources */,
4BC216890A444BDE00BDA09F /* JackServerGlobals.cpp in Sources */,
4B44FAE80C7598370033A72C /* JackServerLaunch.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};


+ 30
- 17
windows/JackWinNamedPipeClientChannel.cpp View File

@@ -36,35 +36,48 @@ JackWinNamedPipeClientChannel::~JackWinNamedPipeClientChannel()
delete fThread;
}

int JackWinNamedPipeClientChannel::ServerCheck(const char* server_name)
{
JackLog("JackWinNamedPipeClientChannel::ServerCheck = %s\n", server_name);
// Connect to server
if (fRequestPipe.Connect(jack_server_dir, 0) < 0) {
jack_error("Cannot connect to server pipe");
return -1;
} else {
return 0;
}
}

int JackWinNamedPipeClientChannel::Open(const char* name, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status)
{
{
int result = 0;
JackLog("JackWinNamedPipeClientChannel::Open name = %s\n", name);
/*
/*
16/08/07: was called before doing "fRequestPipe.Connect" .... still necessary?
if (fNotificationListenPipe.Bind(jack_client_dir, name, 0) < 0) {
jack_error("Cannot bind pipe");
goto error;
}
}
*/
if (fRequestPipe.Connect(jack_server_dir, 0) < 0) {
jack_error("Cannot connect to server pipe");
goto error;
}
// Check name in server
ClientCheck(name, name_res, (int)options, (int*)status, &result);
if (result < 0) {
jack_error("Client name = %s conflits with another running client", name);
goto error;
}
if (fNotificationListenPipe.Bind(jack_client_dir, name_res, 0) < 0) {
jack_error("Cannot bind pipe");
goto error;
}
}
// Check name in server
ClientCheck(name, name_res, (int)options, (int*)status, &result);
if (result < 0) {
jack_error("Client name = %s conflits with another running client", name);
goto error;
}
if (fNotificationListenPipe.Bind(jack_client_dir, name_res, 0) < 0) {
jack_error("Cannot bind pipe");
goto error;
}

fClient = obj;


+ 2
- 0
windows/JackWinNamedPipeClientChannel.h View File

@@ -55,6 +55,8 @@ class JackWinNamedPipeClientChannel : public JackClientChannelInterface, public

int Start();
void Stop();
int ServerCheck(const char* server_name);

void ClientCheck(const char* name, char* name_res, int options, int* status, int* result);
void ClientOpen(const char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result);


Loading…
Cancel
Save