From 3c0d95db608e532bb7caee50d7e92495a4ab168b Mon Sep 17 00:00:00 2001 From: Torben Hohn Date: Sat, 17 Apr 2010 08:53:11 +0200 Subject: [PATCH] some progress on jack-session --- common/JackAPI.cpp | 8 + common/JackChannel.h | 2 +- common/JackClient.cpp | 22 ++- common/JackClientControl.h | 8 + common/JackEngine.cpp | 39 ++++- common/JackEngine.h | 7 +- common/JackLockedEngine.h | 4 +- common/JackRequest.h | 52 +++++- common/jack/types.h | 9 +- example-clients/session_notify.c | 183 +++++++++++++++++++++ example-clients/simple_session_client.c | 202 ++++++++++++++++++++++++ example-clients/wscript | 2 + posix/JackSocketClientChannel.cpp | 21 ++- posix/JackSocketClientChannel.h | 2 +- posix/JackSocketServerChannel.cpp | 4 +- 15 files changed, 544 insertions(+), 21 deletions(-) create mode 100644 example-clients/session_notify.c create mode 100644 example-clients/simple_session_client.c diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 370761a9..174dc480 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -1891,4 +1891,12 @@ EXPORT jack_session_command_t *jack_session_notify(jack_client_t* ext_client, co } } +EXPORT void jack_session_event_free(jack_session_event_t* ev) +{ + free((void *)ev->session_dir); + free((void *)ev->client_uuid); + if (ev->command_line) + free(ev->command_line); + free(ev); +} diff --git a/common/JackChannel.h b/common/JackChannel.h index c52937d6..ce4ae6d4 100644 --- a/common/JackChannel.h +++ b/common/JackChannel.h @@ -127,7 +127,7 @@ class JackClientChannelInterface virtual void InternalClientUnload(int refnum, int int_ref, int* status, int* result) {} - virtual void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, int *result) + virtual void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, jack_session_command_t **result) {} }; diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 637d891b..c2ded587 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -272,6 +272,22 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, fInfoShutdown = NULL; } break; + + case kSessionCallback: + jack_log("JackClient::kSessionCallback"); + if (fSession) { + jack_session_event_t *event = (jack_session_event_t *) malloc( sizeof(jack_session_event_t) ); + char uuid_buf[32]; + event->type = (jack_session_event_type_t) value1; + event->session_dir = strdup( message ); + event->command_line = NULL; + event->flags = (jack_session_flags_t) 0; + snprintf( uuid_buf, sizeof(uuid_buf), "%d", GetClientControl()->fSessionID ); + event->client_uuid = strdup( uuid_buf ); + + fSession(event, fSessionArg); + } + break; } } @@ -1057,7 +1073,11 @@ void JackClient::InternalClientUnload(int ref, jack_status_t* status) jack_session_command_t *JackClient::SessionNotify( const char* target, jack_session_event_type_t type, const char* path ) { - return NULL; + printf( "yo man\n" ); + sleep(1); + jack_session_command_t *res; + fChannel->SessionNotify( GetClientControl()->fRefNum, target, type, path, &res ); + return res; } diff --git a/common/JackClientControl.h b/common/JackClientControl.h index a82313c7..3df92cb6 100644 --- a/common/JackClientControl.h +++ b/common/JackClientControl.h @@ -26,6 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackSynchro.h" #include "JackNotification.h" +#include "jack/session.h" + namespace Jack { @@ -44,6 +46,10 @@ struct JackClientControl : public JackShmMemAble int fPID; bool fActive; + int fSessionID; + char fSessionCommand[256 + 1]; + jack_session_flags_t fSessionFlags; + JackClientControl(const char* name, int pid, int refnum) { Init(name, pid, refnum); @@ -77,6 +83,8 @@ struct JackClientControl : public JackShmMemAble fTransportSync = false; fTransportTimebase = false; fActive = false; + + fSessionID = 0; } } POST_PACKED_STRUCTURE; diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index ea5d9bf8..eb99b65f 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -863,10 +863,45 @@ int JackEngine::PortRename(int refnum, jack_port_id_t port, const char* name) return 0; } -void JackEngine::SessionNotify(int refnum, const char *target, jack_session_event_type_t type, const char *path, int *result ) +void JackEngine::SessionNotify(int refnum, const char *target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket ) { + if (fSessionPendingReplies != 0) { + JackSessionNotifyResult res(-1); + res.Write(socket); + return; + } + + fSessionResult = new JackSessionNotifyResult(); + + for (int i = 0; i < CLIENT_NUM; i++) { + JackClientInterface* client = fClientTable[i]; + if (client && client->GetClientControl()->fCallback[kSessionCallback]) { + + // check if this is a notification to a specific client. + if (target!=NULL && strlen(target)!=0) { + if (strcmp(target, client->GetClientControl()->fName)) { + continue; + } + } + + int result = client->ClientNotify(i, client->GetClientControl()->fName, kSessionCallback, true, path, (int) type, 0); + if (result == 2) { + fSessionPendingReplies += 1; + } else if (result == 1) { + char uuid_buf[32]; + snprintf( uuid_buf, sizeof(uuid_buf), "%d", client->GetClientControl()->fSessionID ); + fSessionResult->fCommandList.push_back( JackSessionCommand( uuid_buf, + client->GetClientControl()->fName, + client->GetClientControl()->fSessionCommand, + client->GetClientControl()->fSessionFlags )); + } + + + + } + } // yay... :( - *result = 0; + //*result = 0; } diff --git a/common/JackEngine.h b/common/JackEngine.h index 5c52c3b0..5e9b39ad 100644 --- a/common/JackEngine.h +++ b/common/JackEngine.h @@ -52,6 +52,11 @@ class SERVER_EXPORT JackEngine : public JackLockAble JackProcessSync fSignal; jack_time_t fLastSwitchUsecs; + int fSessionPendingReplies; + JackChannelTransaction *fSessionTransaction; + JackSessionNotifyResult *fSessionResult; + + int ClientCloseAux(int refnum, JackClientInterface* client, bool wait); void CheckXRun(jack_time_t callback_usecs); @@ -132,7 +137,7 @@ class SERVER_EXPORT JackEngine : public JackLockAble void NotifyFreewheel(bool onoff); void NotifyQuit(); - void SessionNotify( int refnum, const char *target, jack_session_event_type_t type, const char *path, int *result ); + void SessionNotify( int refnum, const char *target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket ); }; diff --git a/common/JackLockedEngine.h b/common/JackLockedEngine.h index c52f1007..8d82b077 100644 --- a/common/JackLockedEngine.h +++ b/common/JackLockedEngine.h @@ -307,11 +307,11 @@ class SERVER_EXPORT JackLockedEngine CATCH_EXCEPTION } - void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, int *result) + void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket) { TRY_CALL JackLock lock(&fEngine); - return fEngine.SessionNotify( refnum, target, type, path, result ); + fEngine.SessionNotify( refnum, target, type, path, socket ); CATCH_EXCEPTION } diff --git a/common/JackRequest.h b/common/JackRequest.h index 76e105ae..33b7936e 100644 --- a/common/JackRequest.h +++ b/common/JackRequest.h @@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "types.h" #include #include +#include namespace Jack { @@ -1071,28 +1072,69 @@ struct JackClientNotificationRequest : public JackRequest } POST_PACKED_STRUCTURE; +struct JackSessionCommand +{ + char fUUID[32]; + char fClientName[JACK_CLIENT_NAME_SIZE+1]; + char fCommand[MAX_PATH+1]; + jack_session_flags_t fFlags; + + JackSessionCommand() + {} + + JackSessionCommand( const char *uuid, const char *clientname, const char *command, jack_session_flags_t flags ) + { + strncpy( fUUID, uuid, sizeof(fUUID)); + strncpy( fClientName, clientname, sizeof(fClientName)); + strncpy( fCommand, command, sizeof(fCommand)); + fFlags = flags; + } +}; + + struct JackSessionNotifyResult : public JackResult { - int fStatus; + std::list fCommandList; JackSessionNotifyResult(): JackResult() {} - JackSessionNotifyResult(int32_t result, int status) - : JackResult(result), fStatus(status) + JackSessionNotifyResult(int32_t result) + : JackResult(result) {} int Read(JackChannelTransaction* trans) { CheckRes(JackResult::Read(trans)); - CheckRes(trans->Read(&fStatus, sizeof(int))); + while(1) { + JackSessionCommand buffer; + + CheckRes(trans->Read(buffer.fUUID, sizeof(buffer.fUUID))); + if (buffer.fUUID[0] == '\0') + break; + + CheckRes(trans->Read(buffer.fClientName, sizeof(buffer.fClientName))); + CheckRes(trans->Read(buffer.fCommand, sizeof(buffer.fCommand))); + CheckRes(trans->Read(&(buffer.fFlags), sizeof(buffer.fFlags))); + + fCommandList.push_back(buffer); + } return 0; } int Write(JackChannelTransaction* trans) { + char terminator[32]; + terminator[0] = '\0'; + CheckRes(JackResult::Write(trans)); - CheckRes(trans->Write(&fStatus, sizeof(int))); + for (std::list::iterator i=fCommandList.begin(); i!=fCommandList.end(); i++) { + CheckRes(trans->Write(i->fUUID, sizeof(i->fUUID))); + CheckRes(trans->Write(i->fClientName, sizeof(i->fClientName))); + CheckRes(trans->Write(i->fCommand, sizeof(i->fCommand))); + CheckRes(trans->Write(&(i->fFlags), sizeof(i->fFlags))); + } + CheckRes(trans->Write(terminator, sizeof(terminator))); return 0; } diff --git a/common/jack/types.h b/common/jack/types.h index 3722d7f4..9cd1ca97 100644 --- a/common/jack/types.h +++ b/common/jack/types.h @@ -345,11 +345,16 @@ enum JackOptions { * Pass optional (char *) load_init string to the * jack_initialize() entry point of an internal client. */ - JackLoadInit = 0x10 + JackLoadInit = 0x10, + + /** + * pass a SessionID Token this allows the sessionmanager to identify the client again. + */ + JackSessionID = 0x20 }; /** Valid options for opening an external client. */ -#define JackOpenOptions (JackServerName|JackNoStartServer|JackUseExactName) +#define JackOpenOptions (JackSessionID|JackServerName|JackNoStartServer|JackUseExactName) /** Valid options for loading an internal client. */ #define JackLoadOptions (JackLoadInit|JackLoadName|JackUseExactName) diff --git a/example-clients/session_notify.c b/example-clients/session_notify.c new file mode 100644 index 00000000..70bec627 --- /dev/null +++ b/example-clients/session_notify.c @@ -0,0 +1,183 @@ +/* + * session_notify.c -- ultra minimal session manager + * + * Copyright (C) 2010 Torben Hohn. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *package; /* program name */ +jack_client_t *client; + +jack_session_event_type_t notify_type; +char *save_path = NULL; + +void jack_shutdown(void *arg) +{ + fprintf(stderr, "JACK shut down, exiting ...\n"); + exit(1); +} + +void signal_handler(int sig) +{ + jack_client_close(client); + fprintf(stderr, "signal received, exiting ...\n"); + exit(0); +} + +void parse_arguments(int argc, char *argv[]) +{ + + /* basename $0 */ + package = strrchr(argv[0], '/'); + if (package == 0) + package = argv[0]; + else + package++; + + if (argc==2) { + if( !strcmp( argv[1], "quit" ) ) { + notify_type = JackSessionSaveAndQuit; + return; + } + } + if (argc==3) { + if( !strcmp( argv[1], "save" ) ) { + notify_type = JackSessionSave; + save_path = argv[2]; + return; + } + + } + fprintf(stderr, "usage: %s quit|save [path]\n", package); + exit(9); +} + +typedef struct { + char name[32]; + char uuid[16]; +} uuid_map_t; + +JSList *uuid_map = NULL; + +void add_uuid_mapping( const char *uuid ) { + char *clientname = jack_get_client_name_by_uuid( client, uuid ); + if( !clientname ) { + printf( "error... cant find client for uuid" ); + return; + } + + uuid_map_t *mapping = malloc( sizeof(uuid_map_t) ); + snprintf( mapping->uuid, sizeof(mapping->uuid), "%s", uuid ); + snprintf( mapping->name, sizeof(mapping->name), "%s", clientname ); + uuid_map = jack_slist_append( uuid_map, mapping ); +} + +char *map_port_name_to_uuid_port( const char *port_name ) +{ + JSList *node; + char retval[300]; + char *port_component = strchr( port_name,':' ); + char *client_component = strdup( port_name ); + strchr( client_component, ':' )[0] = '\0'; + + sprintf( retval, "%s", port_name ); + + for( node=uuid_map; node; node=jack_slist_next(node) ) { + uuid_map_t *mapping = node->data; + if( !strcmp( mapping->name, client_component ) ) { + sprintf( retval, "%s%s", mapping->uuid, port_component ); + break; + } + } + + return strdup(retval); +} + +int main(int argc, char *argv[]) +{ + parse_arguments(argc, argv); + jack_session_command_t *retval; + int k,i,j; + + + /* become a JACK client */ + if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) { + fprintf(stderr, "JACK server not running?\n"); + exit(1); + } + + signal(SIGQUIT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGHUP, signal_handler); + signal(SIGINT, signal_handler); + + jack_on_shutdown(client, jack_shutdown, 0); + + jack_activate(client); + + + retval = jack_session_notify( client, NULL, notify_type, save_path ); + printf( "retval = %p\n", retval ); + for(i=0; retval[i].uuid; i++ ) { + printf( "export SESSION_DIR=\"%s%s/\"\n", save_path, retval[i].client_name ); + printf( "%s &\n", retval[i].command ); + add_uuid_mapping(retval[i].uuid); + } + + printf( "sleep 10\n" ); + + for(k=0; retval[k].uuid; k++ ) { + + char* port_regexp = alloca( jack_client_name_size()+3 ); + char* client_name = jack_get_client_name_by_uuid( client, retval[k].uuid ); + snprintf( port_regexp, jack_client_name_size()+3, "%s:.*", client_name ); + jack_free(client_name); + const char **ports = jack_get_ports( client, port_regexp, NULL, 0 ); + if( !ports ) { + continue; + } + for (i = 0; ports[i]; ++i) { + const char **connections; + if ((connections = jack_port_get_all_connections (client, jack_port_by_name(client, ports[i]))) != 0) { + for (j = 0; connections[j]; j++) { + char *src = map_port_name_to_uuid_port( ports[i] ); + char *dst = map_port_name_to_uuid_port( connections[j] ); + printf( "jack_connect -u \"%s\" \"%s\"\n", src, dst ); + } + jack_free (connections); + } + } + jack_free(ports); + + } + jack_session_commands_free(retval); + + jack_client_close(client); + + return 0; +} diff --git a/example-clients/simple_session_client.c b/example-clients/simple_session_client.c new file mode 100644 index 00000000..2400674d --- /dev/null +++ b/example-clients/simple_session_client.c @@ -0,0 +1,202 @@ +/** @file simple_session_client.c + * + * @brief This simple client demonstrates the most basic features of JACK + * as they would be used by many applications. + * this version also adds session manager functionality. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +jack_port_t *input_port; +jack_port_t *output_port; +jack_client_t *client; + +int simple_quit = 0; + +/** + * The process callback for this JACK application is called in a + * special realtime thread once for each audio cycle. + * + * This client does nothing more than copy data from its input + * port to its output port. It will exit when stopped by + * the user (e.g. using Ctrl-C on a unix-ish operating system) + */ +int +process (jack_nframes_t nframes, void *arg) +{ + jack_default_audio_sample_t *in, *out; + + in = jack_port_get_buffer (input_port, nframes); + out = jack_port_get_buffer (output_port, nframes); + memcpy (out, in, + sizeof (jack_default_audio_sample_t) * nframes); + + return 0; +} + +void +session_callback (jack_session_event_t *event, void *arg) +{ + char retval[100]; + printf ("session notification\n"); + printf ("path %s, uuid %s, type: %s\n", event->session_dir, event->client_uuid, event->type == JackSessionSave ? "save" : "quit"); + + + snprintf (retval, 100, "jack_simple_session_client %s", event->client_uuid); + event->command_line = strdup (retval); + + jack_session_reply( client, event ); + + if (event->type == JackSessionSaveAndQuit) { + simple_quit = 1; + } + + jack_session_event_free (event); +} + +/** + * JACK calls this shutdown_callback if the server ever shuts down or + * decides to disconnect the client. + */ +void +jack_shutdown (void *arg) +{ + exit (1); +} + +int +main (int argc, char *argv[]) +{ + const char **ports; + const char *client_name = "simple"; + jack_status_t status; + + /* open a client connection to the JACK server */ + + if( argc == 1 ) + client = jack_client_open (client_name, JackNullOption, &status ); + else if( argc == 2 ) + client = jack_client_open (client_name, JackSessionID, &status, argv[1] ); + + if (client == NULL) { + fprintf (stderr, "jack_client_open() failed, " + "status = 0x%2.0x\n", status); + if (status & JackServerFailed) { + fprintf (stderr, "Unable to connect to JACK server\n"); + } + exit (1); + } + if (status & JackServerStarted) { + fprintf (stderr, "JACK server started\n"); + } + if (status & JackNameNotUnique) { + client_name = jack_get_client_name(client); + fprintf (stderr, "unique name `%s' assigned\n", client_name); + } + + /* tell the JACK server to call `process()' whenever + there is work to be done. + */ + + jack_set_process_callback (client, process, 0); + + /* tell the JACK server to call `jack_shutdown()' if + it ever shuts down, either entirely, or if it + just decides to stop calling us. + */ + + jack_on_shutdown (client, jack_shutdown, 0); + + /* tell the JACK server to call `session_callback()' if + the session is saved. + */ + + jack_set_session_callback (client, session_callback, NULL); + + /* display the current sample rate. + */ + + printf ("engine sample rate: %" PRIu32 "\n", + jack_get_sample_rate (client)); + + /* create two ports */ + + input_port = jack_port_register (client, "input", + JACK_DEFAULT_AUDIO_TYPE, + JackPortIsInput, 0); + output_port = jack_port_register (client, "output", + JACK_DEFAULT_AUDIO_TYPE, + JackPortIsOutput, 0); + + if ((input_port == NULL) || (output_port == NULL)) { + fprintf(stderr, "no more JACK ports available\n"); + exit (1); + } + + /* Tell the JACK server that we are ready to roll. Our + * process() callback will start running now. */ + + if (jack_activate (client)) { + fprintf (stderr, "cannot activate client"); + exit (1); + } + + /* Connect the ports. You can't do this before the client is + * activated, because we can't make connections to clients + * that aren't running. Note the confusing (but necessary) + * orientation of the driver backend ports: playback ports are + * "input" to the backend, and capture ports are "output" from + * it. + */ + + + /* only do the autoconnect when not reloading from a session. + * in case of a session reload, the SM will restore our connections + */ + + if (argc==1) { + + ports = jack_get_ports (client, NULL, NULL, + JackPortIsPhysical|JackPortIsOutput); + if (ports == NULL) { + fprintf(stderr, "no physical capture ports\n"); + exit (1); + } + + if (jack_connect (client, ports[0], jack_port_name (input_port))) { + fprintf (stderr, "cannot connect input ports\n"); + } + + free (ports); + + ports = jack_get_ports (client, NULL, NULL, + JackPortIsPhysical|JackPortIsInput); + if (ports == NULL) { + fprintf(stderr, "no physical playback ports\n"); + exit (1); + } + + if (jack_connect (client, jack_port_name (output_port), ports[0])) { + fprintf (stderr, "cannot connect output ports\n"); + } + + free (ports); + } + + /* keep running until until we get a quit event */ + + while (!simple_quit) + sleep(1); + + + jack_client_close (client); + exit (0); +} diff --git a/example-clients/wscript b/example-clients/wscript index efa28279..74ccf605 100644 --- a/example-clients/wscript +++ b/example-clients/wscript @@ -22,6 +22,8 @@ example_programs = { 'jack_monitor_client' : 'monitor_client.c', 'jack_thru' : 'thru_client.c', 'jack_cpu_load' : 'cpu_load.c', + 'jack_simple_session_client' : 'simple_session_client.c', + 'jack_session_notify' : 'session_notify.c', 'jack_server_control' : 'server_control.cpp', } diff --git a/posix/JackSocketClientChannel.cpp b/posix/JackSocketClientChannel.cpp index 0ef402e6..3bf56045 100644 --- a/posix/JackSocketClientChannel.cpp +++ b/posix/JackSocketClientChannel.cpp @@ -246,14 +246,29 @@ void JackSocketClientChannel::SetFreewheel(int onoff, int* result) ServerSyncCall(&req, &res, result); } -void JackSocketClientChannel::SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, int* result) +void JackSocketClientChannel::SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t ** result) { JackSessionNotifyRequest req(refnum, target, type, path); - JackResult res; + JackSessionNotifyResult res; int intresult; ServerSyncCall(&req, &res, &intresult); - *result = 0; + jack_session_command_t *session_command = (jack_session_command_t *)malloc( sizeof(jack_session_command_t) * (res.fCommandList.size()+1) ); + int i=0; + + for (std::list::iterator ci=res.fCommandList.begin(); ci!=res.fCommandList.end(); ci++) { + session_command[i].uuid = strdup( ci->fUUID ); + session_command[i].client_name = strdup( ci->fClientName ); + session_command[i].command = strdup( ci->fCommand ); + session_command[i].flags = ci->fFlags; + + i+=1; + } + + session_command[i].uuid = NULL; + + + *result = session_command; } void JackSocketClientChannel::ReleaseTimebase(int refnum, int* result) diff --git a/posix/JackSocketClientChannel.h b/posix/JackSocketClientChannel.h index ac5c90f9..5f20907a 100644 --- a/posix/JackSocketClientChannel.h +++ b/posix/JackSocketClientChannel.h @@ -95,7 +95,7 @@ class JackSocketClientChannel : public detail::JackClientChannelInterface, publi bool Init(); bool Execute(); - void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, int* result); + void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result); }; } // end of namespace diff --git a/posix/JackSocketServerChannel.cpp b/posix/JackSocketServerChannel.cpp index ddb33ac1..b76a1557 100644 --- a/posix/JackSocketServerChannel.cpp +++ b/posix/JackSocketServerChannel.cpp @@ -405,10 +405,8 @@ bool JackSocketServerChannel::HandleRequest(int fd) JackSessionNotifyRequest req; JackSessionNotifyResult res; if (req.Read(socket) == 0) { - fServer->GetEngine()->SessionNotify(req.fRefNum, req.fDst, req.fEventType, req.fPath, &res.fStatus); + fServer->GetEngine()->SessionNotify(req.fRefNum, req.fDst, req.fEventType, req.fPath, socket); } - if (res.Write(socket) < 0) - jack_error("JackRequest::SessionNotify write error ref = %d", req.fRefNum); break; }