25 #include "JackSystemDeps.h"
26 #include "JackLockedEngine.h"
27 #include "JackExternalClient.h"
28 #include "JackInternalClient.h"
29 #include "JackEngineControl.h"
30 #include "JackClientControl.h"
31 #include "JackServerGlobals.h"
32 #include "JackGlobals.h"
33 #include "JackChannel.h"
34 #include "JackError.h"
39 JackEngine::JackEngine(JackGraphManager* manager,
41 JackEngineControl* control)
43 fGraphManager = manager;
44 fSynchroTable = table;
45 fEngineControl = control;
46 for (
int i = 0; i < CLIENT_NUM; i++)
47 fClientTable[i] = NULL;
50 fSessionPendingReplies = 0;
51 fSessionTransaction = NULL;
52 fSessionResult = NULL;
55 JackEngine::~JackEngine()
58 int JackEngine::Open()
63 if (fChannel.Open(fEngineControl->fServerName) < 0) {
71 int JackEngine::Close()
77 for (
int i = fEngineControl->fDriverNum; i < CLIENT_NUM; i++) {
78 if (JackLoadableInternalClient* loadable_client = dynamic_cast<JackLoadableInternalClient*>(fClientTable[i])) {
79 jack_log(
"JackEngine::Close loadable client = %s", loadable_client->GetClientControl()->fName);
80 loadable_client->Close();
82 fClientTable[i] = NULL;
83 delete loadable_client;
84 }
else if (JackExternalClient* external_client = dynamic_cast<JackExternalClient*>(fClientTable[i])) {
85 jack_log(
"JackEngine::Close external client = %s", external_client->GetClientControl()->fName);
86 external_client->Close();
88 fClientTable[i] = NULL;
95 void JackEngine::NotifyQuit()
97 fChannel.NotifyQuit();
104 int JackEngine::AllocateRefnum()
106 for (
int i = 0; i < CLIENT_NUM; i++) {
107 if (!fClientTable[i]) {
108 jack_log(
"JackEngine::AllocateRefNum ref = %ld", i);
115 void JackEngine::ReleaseRefnum(
int ref)
117 fClientTable[ref] = NULL;
119 if (fEngineControl->fTemporary) {
121 for (i = fEngineControl->fDriverNum; i < CLIENT_NUM; i++) {
125 if (i == CLIENT_NUM) {
127 jack_log(
"JackEngine::ReleaseRefnum server quit");
128 fEngineControl->fTemporary =
false;
129 throw JackTemporaryException();
138 void JackEngine::ProcessNext(jack_time_t cur_cycle_begin)
140 fLastSwitchUsecs = cur_cycle_begin;
141 if (fGraphManager->RunNextGraph()) {
142 fChannel.Notify(ALL_CLIENTS, kGraphOrderCallback, 0);
147 void JackEngine::ProcessCurrent(jack_time_t cur_cycle_begin)
149 if (cur_cycle_begin < fLastSwitchUsecs + 2 * fEngineControl->fPeriodUsecs)
150 CheckXRun(cur_cycle_begin);
151 fGraphManager->RunCurrentGraph();
154 bool JackEngine::Process(jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end)
159 fEngineControl->CycleBegin(fClientTable, fGraphManager, cur_cycle_begin, prev_cycle_end);
162 if (fGraphManager->IsFinishedGraph()) {
163 ProcessNext(cur_cycle_begin);
166 jack_log(
"Process: graph not finished!");
167 if (cur_cycle_begin > fLastSwitchUsecs + fEngineControl->fTimeOutUsecs) {
168 jack_log(
"Process: switch to next state delta = %ld",
long(cur_cycle_begin - fLastSwitchUsecs));
169 ProcessNext(cur_cycle_begin);
172 jack_log(
"Process: waiting to switch delta = %ld",
long(cur_cycle_begin - fLastSwitchUsecs));
173 ProcessCurrent(cur_cycle_begin);
179 fEngineControl->CycleEnd(fClientTable);
188 void JackEngine::CheckXRun(jack_time_t callback_usecs)
190 for (
int i = fEngineControl->fDriverNum; i < CLIENT_NUM; i++) {
191 JackClientInterface* client = fClientTable[i];
192 if (client && client->GetClientControl()->fActive) {
193 JackClientTiming* timing = fGraphManager->GetClientTiming(i);
194 jack_client_state_t status = timing->fStatus;
195 jack_time_t finished_date = timing->fFinishedAt;
197 if (status != NotTriggered && status != Finished) {
198 jack_error(
"JackEngine::XRun: client = %s was not run: state = %ld", client->GetClientControl()->fName, status);
199 fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0);
202 if (status == Finished && (
long)(finished_date - callback_usecs) > 0) {
203 jack_error(
"JackEngine::XRun: client %s finished after current callback", client->GetClientControl()->fName);
204 fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0);
210 int JackEngine::ComputeTotalLatencies()
212 std::vector<jack_int_t> sorted;
213 std::vector<jack_int_t>::iterator it;
214 std::vector<jack_int_t>::reverse_iterator rit;
216 fGraphManager->TopologicalSort(sorted);
222 for (it = sorted.begin(); it != sorted.end(); it++) {
223 NotifyClient(*it, kLatencyCallback,
true,
"", 0, 0);
228 for (rit = sorted.rbegin(); rit != sorted.rend(); rit++) {
229 NotifyClient(*rit, kLatencyCallback,
true,
"", 1, 0);
239 void JackEngine::NotifyClient(
int refnum,
int event,
int sync,
const char* message,
int value1,
int value2)
241 JackClientInterface* client = fClientTable[refnum];
246 if (client->GetClientControl()->fCallback[event]) {
251 if (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, message, value1, value2) < 0)
252 jack_error(
"NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2);
257 jack_log(
"JackEngine::NotifyClient: no callback for event = %ld", event);
262 void JackEngine::NotifyClients(
int event,
int sync,
const char* message,
int value1,
int value2)
264 for (
int i = 0; i < CLIENT_NUM; i++) {
265 NotifyClient(i, event, sync, message, value1, value2);
269 int JackEngine::NotifyAddClient(JackClientInterface* new_client,
const char* name,
int refnum)
271 jack_log(
"JackEngine::NotifyAddClient: name = %s", name);
273 for (
int i = 0; i < CLIENT_NUM; i++) {
274 JackClientInterface* old_client = fClientTable[i];
275 if (old_client && old_client != new_client) {
276 if (old_client->ClientNotify(refnum, name, kAddClient,
false,
"", 0, 0) < 0) {
277 jack_error(
"NotifyAddClient old_client fails name = %s", old_client->GetClientControl()->fName);
280 if (new_client->ClientNotify(i, old_client->GetClientControl()->fName, kAddClient,
true,
"", 0, 0) < 0) {
281 jack_error(
"NotifyAddClient new_client fails name = %s", name);
290 void JackEngine::NotifyRemoveClient(
const char* name,
int refnum)
293 for (
int i = 0; i < CLIENT_NUM; i++) {
294 JackClientInterface* client = fClientTable[i];
296 client->ClientNotify(refnum, name, kRemoveClient,
false,
"", 0, 0);
302 void JackEngine::NotifyXRun(jack_time_t callback_usecs,
float delayed_usecs)
305 fEngineControl->NotifyXRun(callback_usecs, delayed_usecs);
306 fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0);
309 void JackEngine::NotifyXRun(
int refnum)
311 if (refnum == ALL_CLIENTS) {
312 NotifyClients(kXRunCallback,
false,
"", 0, 0);
314 NotifyClient(refnum, kXRunCallback,
false,
"", 0, 0);
318 void JackEngine::NotifyGraphReorder()
320 NotifyClients(kGraphOrderCallback,
false,
"", 0, 0);
321 ComputeTotalLatencies();
324 void JackEngine::NotifyBufferSize(jack_nframes_t buffer_size)
326 NotifyClients(kBufferSizeCallback,
true,
"", buffer_size, 0);
329 void JackEngine::NotifySampleRate(jack_nframes_t sample_rate)
331 NotifyClients(kSampleRateCallback,
true,
"", sample_rate, 0);
334 void JackEngine::NotifyFailure(
int code,
const char* reason)
336 NotifyClients(kShutDownCallback,
false, reason, code, 0);
339 void JackEngine::NotifyFreewheel(
bool onoff)
343 fEngineControl->fSavedRealTime = fEngineControl->fRealTime;
344 fEngineControl->fRealTime =
false;
347 fEngineControl->fRealTime = fEngineControl->fSavedRealTime;
348 fEngineControl->fSavedRealTime =
false;
350 NotifyClients((onoff ? kStartFreewheelCallback : kStopFreewheelCallback),
true,
"", 0, 0);
353 void JackEngine::NotifyPortRegistation(jack_port_id_t port_index,
bool onoff)
355 NotifyClients((onoff ? kPortRegistrationOnCallback : kPortRegistrationOffCallback),
false,
"", port_index, 0);
358 void JackEngine::NotifyPortRename(jack_port_id_t port,
const char* old_name)
360 NotifyClients(kPortRenameCallback,
false, old_name, port, 0);
363 void JackEngine::NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst,
bool onoff)
365 NotifyClients((onoff ? kPortConnectCallback : kPortDisconnectCallback),
false,
"", src, dst);
368 void JackEngine::NotifyActivate(
int refnum)
370 NotifyClient(refnum, kActivateClient,
true,
"", 0, 0);
377 int JackEngine::GetInternalClientName(
int refnum,
char* name_res)
379 JackClientInterface* client = fClientTable[refnum];
380 strncpy(name_res, client->GetClientControl()->fName, JACK_CLIENT_NAME_SIZE);
384 int JackEngine::InternalClientHandle(
const char* client_name,
int* status,
int* int_ref)
389 for (
int i = 0; i < CLIENT_NUM; i++) {
390 JackClientInterface* client = fClientTable[i];
391 if (client && dynamic_cast<JackLoadableInternalClient*>(client) && (strcmp(client->GetClientControl()->fName, client_name) == 0)) {
392 jack_log(
"InternalClientHandle found client name = %s ref = %ld", client_name, i);
398 *status |= (JackNoSuchClient | JackFailure);
402 int JackEngine::InternalClientUnload(
int refnum,
int* status)
404 JackClientInterface* client = fClientTable[refnum];
406 int res = client->Close();
411 *status = (JackNoSuchClient | JackFailure);
420 int JackEngine::ClientCheck(
const char* name,
int uuid,
char* name_res,
int protocol,
int options,
int* status)
424 strcpy(name_res, name);
426 jack_log(
"Check protocol client = %ld server = %ld", protocol, JACK_PROTOCOL_VERSION);
428 if (protocol != JACK_PROTOCOL_VERSION) {
429 *status |= (JackFailure | JackVersionError);
430 jack_error(
"JACK protocol mismatch (%d vs %d)", protocol, JACK_PROTOCOL_VERSION);
434 std::map<int,std::string>::iterator res = fReservationMap.find(uuid);
436 if (res != fReservationMap.end()) {
437 strncpy(name_res, res->second.c_str(), JACK_CLIENT_NAME_SIZE);
438 }
else if (ClientCheckName(name)) {
440 *status |= JackNameNotUnique;
442 if (options & JackUseExactName) {
443 jack_error(
"cannot create new client; %s already exists", name);
444 *status |= JackFailure;
448 if (GenerateUniqueName(name_res)) {
449 *status |= JackFailure;
457 bool JackEngine::GenerateUniqueName(
char* name)
460 int length = strlen(name);
462 if (length > JACK_CLIENT_NAME_SIZE - 4) {
463 jack_error(
"%s exists and is too long to make unique", name);
468 name[length++] =
'-';
475 while (ClientCheckName(name)) {
476 if (name[ones] ==
'9') {
477 if (name[tens] ==
'9') {
478 jack_error(
"client %s has 99 extra instances already", name);
490 bool JackEngine::ClientCheckName(
const char* name)
492 for (
int i = 0; i < CLIENT_NUM; i++) {
493 JackClientInterface* client = fClientTable[i];
494 if (client && (strcmp(client->GetClientControl()->fName, name) == 0))
498 for (std::map<int,std::string>::iterator i = fReservationMap.begin(); i != fReservationMap.end(); i++) {
499 if (i->second == name)
506 int JackEngine::GetNewUUID()
511 void JackEngine::EnsureUUID(
int uuid)
516 for (
int i = 0; i < CLIENT_NUM; i++) {
517 JackClientInterface* client = fClientTable[i];
518 if (client && (client->GetClientControl()->fSessionID == uuid)) {
519 client->GetClientControl()->fSessionID = GetNewUUID();
524 int JackEngine::GetClientPID(
const char* name)
526 for (
int i = 0; i < CLIENT_NUM; i++) {
527 JackClientInterface* client = fClientTable[i];
528 if (client && (strcmp(client->GetClientControl()->fName, name) == 0))
529 return client->GetClientControl()->fPID;
535 int JackEngine::GetClientRefNum(
const char* name)
537 for (
int i = 0; i < CLIENT_NUM; i++) {
538 JackClientInterface* client = fClientTable[i];
539 if (client && (strcmp(client->GetClientControl()->fName, name) == 0))
540 return client->GetClientControl()->fRefNum;
547 int JackEngine::ClientExternalOpen(
const char* name,
int pid,
int uuid,
int* ref,
int* shared_engine,
int* shared_client,
int* shared_graph_manager)
549 char real_name[JACK_CLIENT_NAME_SIZE + 1];
553 strncpy(real_name, name, JACK_CLIENT_NAME_SIZE);
555 std::map<int, std::string>::iterator res = fReservationMap.find(uuid);
556 if (res != fReservationMap.end()) {
557 strncpy(real_name, res->second.c_str(), JACK_CLIENT_NAME_SIZE);
558 fReservationMap.erase(uuid);
560 strncpy(real_name, name, JACK_CLIENT_NAME_SIZE);
565 jack_log(
"JackEngine::ClientExternalOpen: uuid = %d, name = %s ", uuid, real_name);
567 int refnum = AllocateRefnum();
573 JackExternalClient* client =
new JackExternalClient();
575 if (!fSynchroTable[refnum].Allocate(real_name, fEngineControl->fServerName, 0)) {
580 if (client->Open(real_name, pid, refnum, uuid, shared_client) < 0) {
585 if (!fSignal.LockedTimedWait(DRIVER_OPEN_TIMEOUT * 1000000)) {
591 fClientTable[refnum] = client;
593 if (NotifyAddClient(client, real_name, refnum) < 0) {
598 fGraphManager->InitRefNum(refnum);
599 fEngineControl->ResetRollingUsecs();
600 *shared_engine = fEngineControl->GetShmIndex();
601 *shared_graph_manager = fGraphManager->GetShmIndex();
607 fSynchroTable[refnum].Destroy();
608 fClientTable[refnum] = 0;
615 int JackEngine::ClientInternalOpen(
const char* name,
int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client,
bool wait)
617 jack_log(
"JackEngine::ClientInternalOpen: name = %s", name);
619 int refnum = AllocateRefnum();
625 if (!fSynchroTable[refnum].Allocate(name, fEngineControl->fServerName, 0)) {
630 if (wait && !fSignal.LockedTimedWait(DRIVER_OPEN_TIMEOUT * 1000000)) {
636 fClientTable[refnum] = client;
638 if (NotifyAddClient(client, name, refnum) < 0) {
643 fGraphManager->InitRefNum(refnum);
644 fEngineControl->ResetRollingUsecs();
645 *shared_engine = fEngineControl;
646 *shared_manager = fGraphManager;
652 fSynchroTable[refnum].Destroy();
653 fClientTable[refnum] = 0;
658 int JackEngine::ClientExternalClose(
int refnum)
660 JackClientInterface* client = fClientTable[refnum];
661 fEngineControl->fTransport.ResetTimebase(refnum);
662 int res = ClientCloseAux(refnum, client,
true);
669 int JackEngine::ClientInternalClose(
int refnum,
bool wait)
671 JackClientInterface* client = fClientTable[refnum];
672 return ClientCloseAux(refnum, client, wait);
675 int JackEngine::ClientCloseAux(
int refnum, JackClientInterface* client,
bool wait)
677 jack_log(
"JackEngine::ClientCloseAux ref = %ld", refnum);
680 jack_int_t ports[PORT_NUM_FOR_CLIENT];
683 fGraphManager->GetInputPorts(refnum, ports);
684 for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY); i++) {
685 PortUnRegister(refnum, ports[i]);
688 fGraphManager->GetOutputPorts(refnum, ports);
689 for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY); i++) {
690 PortUnRegister(refnum, ports[i]);
694 ReleaseRefnum(refnum);
697 fGraphManager->RemoveAllPorts(refnum);
701 if (!fSignal.LockedTimedWait(fEngineControl->fTimeOutUsecs * 2)) {
702 jack_error(
"JackEngine::ClientCloseAux wait error ref = %ld", refnum);
707 NotifyRemoveClient(client->GetClientControl()->fName, client->GetClientControl()->fRefNum);
710 fSynchroTable[refnum].Destroy();
711 fEngineControl->ResetRollingUsecs();
715 int JackEngine::ClientActivate(
int refnum,
bool is_real_time)
717 JackClientInterface* client = fClientTable[refnum];
718 jack_log(
"JackEngine::ClientActivate ref = %ld name = %s", refnum, client->GetClientControl()->fName);
721 fGraphManager->Activate(refnum);
724 if (!fSignal.LockedTimedWait(fEngineControl->fTimeOutUsecs * 10)) {
725 jack_error(
"JackEngine::ClientActivate wait error ref = %ld name = %s", refnum, client->GetClientControl()->fName);
728 jack_int_t input_ports[PORT_NUM_FOR_CLIENT];
729 jack_int_t output_ports[PORT_NUM_FOR_CLIENT];
730 fGraphManager->GetInputPorts(refnum, input_ports);
731 fGraphManager->GetOutputPorts(refnum, output_ports);
734 NotifyActivate(refnum);
737 for (
int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) {
738 NotifyPortRegistation(input_ports[i],
true);
740 for (
int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) {
741 NotifyPortRegistation(output_ports[i],
true);
749 int JackEngine::ClientDeactivate(
int refnum)
751 JackClientInterface* client = fClientTable[refnum];
752 jack_log(
"JackEngine::ClientDeactivate ref = %ld name = %s", refnum, client->GetClientControl()->fName);
754 jack_int_t input_ports[PORT_NUM_FOR_CLIENT];
755 jack_int_t output_ports[PORT_NUM_FOR_CLIENT];
756 fGraphManager->GetInputPorts(refnum, input_ports);
757 fGraphManager->GetOutputPorts(refnum, output_ports);
760 for (
int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) {
761 PortDisconnect(refnum, input_ports[i], ALL_PORTS);
763 for (
int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) {
764 PortDisconnect(refnum, output_ports[i], ALL_PORTS);
768 for (
int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) {
769 NotifyPortRegistation(input_ports[i],
false);
771 for (
int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) {
772 NotifyPortRegistation(output_ports[i],
false);
775 fGraphManager->Deactivate(refnum);
776 fLastSwitchUsecs = 0;
779 if (!fSignal.LockedTimedWait(fEngineControl->fTimeOutUsecs * 10)) {
780 jack_error(
"JackEngine::ClientDeactivate wait error ref = %ld name = %s", refnum, client->GetClientControl()->fName);
791 int JackEngine::PortRegister(
int refnum,
const char* name,
const char *type,
unsigned int flags,
unsigned int buffer_size, jack_port_id_t* port_index)
793 jack_log(
"JackEngine::PortRegister ref = %ld name = %s type = %s flags = %d buffer_size = %d", refnum, name, type, flags, buffer_size);
794 JackClientInterface* client = fClientTable[refnum];
797 if (fGraphManager->GetPort(name) != NO_PORT) {
798 jack_error(
"port_name \"%s\" already exists", name);
803 *port_index = fGraphManager->AllocatePort(refnum, name, type, (JackPortFlags)flags, fEngineControl->fBufferSize);
804 if (*port_index != NO_PORT) {
805 if (client->GetClientControl()->fActive)
806 NotifyPortRegistation(*port_index,
true);
813 int JackEngine::PortUnRegister(
int refnum, jack_port_id_t port_index)
815 jack_log(
"JackEngine::PortUnRegister ref = %ld port_index = %ld", refnum, port_index);
816 JackClientInterface* client = fClientTable[refnum];
819 PortDisconnect(refnum, port_index, ALL_PORTS);
821 if (fGraphManager->ReleasePort(refnum, port_index) == 0) {
822 if (client->GetClientControl()->fActive)
823 NotifyPortRegistation(port_index,
false);
830 int JackEngine::PortConnect(
int refnum,
const char* src,
const char* dst)
832 jack_log(
"JackEngine::PortConnect src = %s dst = %s", src, dst);
833 jack_port_id_t port_src, port_dst;
835 return (fGraphManager->GetTwoPorts(src, dst, &port_src, &port_dst) < 0)
837 : PortConnect(refnum, port_src, port_dst);
840 int JackEngine::PortConnect(
int refnum, jack_port_id_t src, jack_port_id_t dst)
842 jack_log(
"JackEngine::PortConnect src = %d dst = %d", src, dst);
843 JackClientInterface* client;
846 if (fGraphManager->CheckPorts(src, dst) < 0)
849 ref = fGraphManager->GetOutputRefNum(src);
851 client = fClientTable[ref];
853 if (!client->GetClientControl()->fActive) {
854 jack_error(
"Cannot connect ports owned by inactive clients:"
855 " \"%s\" is not active", client->GetClientControl()->fName);
859 ref = fGraphManager->GetInputRefNum(dst);
861 client = fClientTable[ref];
863 if (!client->GetClientControl()->fActive) {
864 jack_error(
"Cannot connect ports owned by inactive clients:"
865 " \"%s\" is not active", client->GetClientControl()->fName);
869 int res = fGraphManager->Connect(src, dst);
871 NotifyPortConnect(src, dst,
true);
875 int JackEngine::PortDisconnect(
int refnum,
const char* src,
const char* dst)
877 jack_log(
"JackEngine::PortDisconnect src = %s dst = %s", src, dst);
878 jack_port_id_t port_src, port_dst;
880 return (fGraphManager->GetTwoPorts(src, dst, &port_src, &port_dst) < 0)
882 : PortDisconnect(refnum, port_src, port_dst);
885 int JackEngine::PortDisconnect(
int refnum, jack_port_id_t src, jack_port_id_t dst)
887 jack_log(
"JackEngine::PortDisconnect src = %d dst = %d", src, dst);
889 if (dst == ALL_PORTS) {
891 jack_int_t connections[CONNECTION_NUM_FOR_PORT];
892 fGraphManager->GetConnections(src, connections);
894 JackPort* port = fGraphManager->GetPort(src);
896 if (port->GetFlags() & JackPortIsOutput) {
897 for (
int i = 0; (i < CONNECTION_NUM_FOR_PORT) && (connections[i] != EMPTY); i++) {
898 if (PortDisconnect(refnum, src, connections[i]) != 0) {
903 for (
int i = 0; (i < CONNECTION_NUM_FOR_PORT) && (connections[i] != EMPTY); i++) {
904 if (PortDisconnect(refnum, connections[i], src) != 0) {
911 }
else if (fGraphManager->CheckPorts(src, dst) < 0) {
913 }
else if (fGraphManager->Disconnect(src, dst) == 0) {
915 NotifyPortConnect(src, dst,
false);
922 int JackEngine::PortRename(
int refnum, jack_port_id_t port,
const char* name)
924 char old_name[REAL_JACK_PORT_NAME_SIZE];
925 strcpy(old_name, fGraphManager->GetPort(port)->GetName());
926 fGraphManager->GetPort(port)->SetName(name);
927 NotifyPortRename(port, old_name);
935 void JackEngine::SessionNotify(
int refnum,
const char *target, jack_session_event_type_t type,
const char *path, JackChannelTransaction *socket, JackSessionNotifyResult** result)
937 if (fSessionPendingReplies != 0) {
938 JackSessionNotifyResult res(-1);
940 jack_log(
"JackEngine::SessionNotify ... busy");
941 if (result != NULL) {
947 for (
int i = 0; i < CLIENT_NUM; i++) {
948 JackClientInterface* client = fClientTable[i];
949 if (client && (client->GetClientControl()->fSessionID < 0)) {
950 client->GetClientControl()->fSessionID = GetNewUUID();
953 fSessionResult =
new JackSessionNotifyResult();
955 for (
int i = 0; i < CLIENT_NUM; i++) {
956 JackClientInterface* client = fClientTable[i];
957 if (client && client->GetClientControl()->fCallback[kSessionCallback]) {
960 if (target != NULL && strlen(target) != 0) {
961 if (strcmp(target, client->GetClientControl()->fName)) {
966 char path_buf[JACK_PORT_NAME_SIZE];
967 snprintf(path_buf,
sizeof(path_buf),
"%s%s%c", path, client->GetClientControl()->fName, DIR_SEPARATOR);
969 int res = JackTools::MkDir(path_buf);
971 jack_error(
"JackEngine::SessionNotify: can not create session directory '%s'", path_buf);
973 int result = client->ClientNotify(i, client->GetClientControl()->fName, kSessionCallback,
true, path_buf, (int)type, 0);
975 if (result == kPendingSessionReply) {
976 fSessionPendingReplies += 1;
977 }
else if (result == kImmediateSessionReply) {
978 char uuid_buf[JACK_UUID_SIZE];
979 snprintf(uuid_buf,
sizeof(uuid_buf),
"%d", client->GetClientControl()->fSessionID);
980 fSessionResult->fCommandList.push_back(JackSessionCommand(uuid_buf,
981 client->GetClientControl()->fName,
982 client->GetClientControl()->fSessionCommand,
983 client->GetClientControl()->fSessionFlags));
988 if (result != NULL) {
989 *result = fSessionResult;
992 if (fSessionPendingReplies == 0) {
993 fSessionResult->Write(socket);
994 if (result == NULL) {
995 delete fSessionResult;
997 fSessionResult = NULL;
999 fSessionTransaction = socket;
1003 void JackEngine::SessionReply(
int refnum)
1005 JackClientInterface* client = fClientTable[refnum];
1006 char uuid_buf[JACK_UUID_SIZE];
1007 snprintf(uuid_buf,
sizeof(uuid_buf),
"%d", client->GetClientControl()->fSessionID);
1008 fSessionResult->fCommandList.push_back(JackSessionCommand(uuid_buf,
1009 client->GetClientControl()->fName,
1010 client->GetClientControl()->fSessionCommand,
1011 client->GetClientControl()->fSessionFlags));
1012 fSessionPendingReplies -= 1;
1014 if (fSessionPendingReplies == 0) {
1015 fSessionResult->Write(fSessionTransaction);
1016 if (fSessionTransaction != NULL)
1018 delete fSessionResult;
1020 fSessionResult = NULL;
1024 void JackEngine::GetUUIDForClientName(
const char *client_name,
char *uuid_res,
int *result)
1026 for (
int i = 0; i < CLIENT_NUM; i++) {
1027 JackClientInterface* client = fClientTable[i];
1029 if (client && (strcmp(client_name, client->GetClientControl()->fName) == 0)) {
1030 snprintf(uuid_res, JACK_UUID_SIZE,
"%d", client->GetClientControl()->fSessionID);
1039 void JackEngine::GetClientNameForUUID(
const char *uuid,
char *name_res,
int *result)
1041 for (
int i = 0; i < CLIENT_NUM; i++) {
1042 JackClientInterface* client = fClientTable[i];
1047 char uuid_buf[JACK_UUID_SIZE];
1048 snprintf(uuid_buf, JACK_UUID_SIZE,
"%d", client->GetClientControl()->fSessionID);
1050 if (strcmp(uuid,uuid_buf) == 0) {
1051 strncpy(name_res, client->GetClientControl()->fName, JACK_CLIENT_NAME_SIZE);
1060 void JackEngine::ReserveClientName(
const char *name,
const char *uuid,
int *result)
1062 jack_log(
"JackEngine::ReserveClientName ( name = %s, uuid = %s )", name, uuid);
1064 if (ClientCheckName(name)) {
1070 EnsureUUID(atoi(uuid));
1071 fReservationMap[atoi(uuid)] = name;
1075 void JackEngine::ClientHasSessionCallback(
const char *name,
int *result)
1077 JackClientInterface* client = NULL;
1078 for (
int i = 0; i < CLIENT_NUM; i++) {
1079 client = fClientTable[i];
1080 if (client && (strcmp(client->GetClientControl()->fName, name) == 0))
1085 *result = client->GetClientControl()->fCallback[kSessionCallback];