jack1 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2293 lines
55KB

  1. /*
  2. Copyright (C) 2001 Paul Davis
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. $Id$
  15. */
  16. #include <unistd.h>
  17. #include <sys/socket.h>
  18. #include <sys/poll.h>
  19. #include <sys/un.h>
  20. #include <sys/stat.h>
  21. #include <errno.h>
  22. #include <fcntl.h>
  23. #include <sys/shm.h>
  24. #include <stdio.h>
  25. #include <stdarg.h>
  26. #include <sys/ipc.h>
  27. #include <signal.h>
  28. #include <sys/types.h>
  29. #include <string.h>
  30. #include <limits.h>
  31. #include <sys/mman.h>
  32. #include <asm/msr.h>
  33. #include <jack/internal.h>
  34. #include <jack/engine.h>
  35. #include <jack/driver.h>
  36. typedef struct {
  37. jack_port_internal_t *source;
  38. jack_port_internal_t *destination;
  39. } jack_connection_internal_t;
  40. typedef struct _jack_client_internal {
  41. jack_client_control_t *control;
  42. int request_fd;
  43. int event_fd;
  44. int subgraph_start_fd;
  45. int subgraph_wait_fd;
  46. GSList *ports; /* protected by engine->graph_lock */
  47. GSList *fed_by; /* protected by engine->graph_lock */
  48. int shm_id;
  49. int shm_key;
  50. unsigned long rank;
  51. struct _jack_client_internal *next_client; /* not a linked list! */
  52. dlhandle handle;
  53. } jack_client_internal_t;
  54. static int jack_port_assign_buffer (jack_engine_t *, jack_port_internal_t *);
  55. static jack_port_internal_t *jack_get_port_by_name (jack_engine_t *, const char *name);
  56. static void jack_client_delete (jack_engine_t *, jack_client_internal_t *);
  57. static void jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client);
  58. static jack_client_internal_t *jack_client_internal_new (jack_engine_t *engine, int fd, jack_client_connect_request_t *);
  59. static jack_client_internal_t *jack_client_internal_by_id (jack_engine_t *engine, jack_client_id_t id);
  60. static void jack_sort_graph (jack_engine_t *engine, int take_lock);
  61. static int jack_rechain_graph (jack_engine_t *engine, int take_lock);
  62. static int jack_get_fifo_fd (jack_engine_t *engine, int which_fifo);
  63. static int jack_port_do_connect (jack_engine_t *engine, const char *source_port, const char *destination_port);
  64. static int jack_port_do_disconnect (jack_engine_t *engine, const char *source_port, const char *destination_port);
  65. static int jack_port_do_unregister (jack_engine_t *engine, jack_request_t *);
  66. static int jack_port_do_register (jack_engine_t *engine, jack_request_t *);
  67. static void jack_port_release (jack_engine_t *engine, jack_port_internal_t *);
  68. static void jack_port_clear_connections (jack_engine_t *engine, jack_port_internal_t *port);
  69. static int jack_port_disconnect_internal (jack_engine_t *engine, jack_port_internal_t *src,
  70. jack_port_internal_t *dst, int sort_graph);
  71. static void jack_port_registration_notify (jack_engine_t *, jack_port_id_t, int);
  72. static int jack_send_connection_notification (jack_engine_t *, jack_client_id_t, jack_port_id_t, jack_port_id_t, int);
  73. static int jack_deliver_event (jack_engine_t *, jack_client_internal_t *, jack_event_t *);
  74. static void jack_audio_port_mixdown (jack_port_t *port, nframes_t nframes);
  75. jack_port_type_info_t builtin_port_types[] = {
  76. { JACK_DEFAULT_AUDIO_TYPE, jack_audio_port_mixdown, 1 },
  77. { 0, NULL }
  78. };
  79. static inline int
  80. jack_client_is_inprocess (jack_client_internal_t *client)
  81. {
  82. return (client->control->type == ClientDynamic) || (client->control->type == ClientDriver);
  83. }
  84. static
  85. void shm_destroy (int status, void *arg)
  86. {
  87. int shm_id = (int) arg;
  88. shmctl (shm_id, IPC_RMID, 0);
  89. }
  90. static int
  91. make_sockets (int fd[2])
  92. {
  93. struct sockaddr_un addr;
  94. int i;
  95. /* First, the master server socket */
  96. if ((fd[0] = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
  97. jack_error ("cannot create server socket (%s)", strerror (errno));
  98. return -1;
  99. }
  100. addr.sun_family = AF_UNIX;
  101. for (i = 0; i < 999; i++) {
  102. snprintf (addr.sun_path, sizeof (addr.sun_path) - 1, "/tmp/jack_%d", i);
  103. if (access (addr.sun_path, F_OK) != 0) {
  104. break;
  105. }
  106. }
  107. if (i == 999) {
  108. jack_error ("all possible server socket names in use!!!");
  109. close (fd[0]);
  110. return -1;
  111. }
  112. if (bind (fd[0], (struct sockaddr *) &addr, sizeof (addr)) < 0) {
  113. jack_error ("cannot bind server to socket (%s)", strerror (errno));
  114. close (fd[0]);
  115. return -1;
  116. }
  117. if (listen (fd[0], 1) < 0) {
  118. jack_error ("cannot enable listen on server socket (%s)", strerror (errno));
  119. close (fd[0]);
  120. return -1;
  121. }
  122. /* Now the client/server event ack server socket */
  123. if ((fd[1] = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
  124. jack_error ("cannot create event ACK socket (%s)", strerror (errno));
  125. close (fd[0]);
  126. return -1;
  127. }
  128. addr.sun_family = AF_UNIX;
  129. for (i = 0; i < 999; i++) {
  130. snprintf (addr.sun_path, sizeof (addr.sun_path) - 1, "/tmp/jack_ack_%d", i);
  131. if (access (addr.sun_path, F_OK) != 0) {
  132. break;
  133. }
  134. }
  135. if (i == 999) {
  136. jack_error ("all possible server ACK socket names in use!!!");
  137. close (fd[0]);
  138. close (fd[1]);
  139. return -1;
  140. }
  141. if (bind (fd[1], (struct sockaddr *) &addr, sizeof (addr)) < 0) {
  142. jack_error ("cannot bind server to socket (%s)", strerror (errno));
  143. close (fd[0]);
  144. close (fd[1]);
  145. return -1;
  146. }
  147. if (listen (fd[1], 1) < 0) {
  148. jack_error ("cannot enable listen on server socket (%s)", strerror (errno));
  149. close (fd[0]);
  150. close (fd[1]);
  151. return -1;
  152. }
  153. return 0;
  154. }
  155. static void
  156. jack_cleanup_clients (jack_engine_t *engine)
  157. {
  158. jack_client_control_t *ctl;
  159. jack_client_internal_t *client;
  160. GSList *node;
  161. GSList *remove = 0;
  162. static int x = 0;
  163. x++;
  164. pthread_mutex_lock (&engine->graph_lock);
  165. for (node = engine->clients; node; node = g_slist_next (node)) {
  166. client = (jack_client_internal_t *) node->data;
  167. ctl = client->control;
  168. printf ("client %s state = %d\n", ctl->name, ctl->state);
  169. if (ctl->state > JACK_CLIENT_STATE_NOT_TRIGGERED) {
  170. remove = g_slist_prepend (remove, node->data);
  171. printf ("%d: removing failed client %s\n", x, ctl->name);
  172. }
  173. }
  174. pthread_mutex_unlock (&engine->graph_lock);
  175. if (remove) {
  176. for (node = remove; node; node = g_slist_next (node)) {
  177. jack_remove_client (engine, (jack_client_internal_t *) node->data);
  178. }
  179. g_slist_free (remove);
  180. }
  181. }
  182. static int
  183. jack_add_port_segment (jack_engine_t *engine, unsigned long nports)
  184. {
  185. jack_port_segment_info_t *si;
  186. key_t key;
  187. int id;
  188. char *addr;
  189. int offset;
  190. size_t size;
  191. size_t step;
  192. key = random();
  193. size = nports * sizeof (sample_t) * engine->control->buffer_size;
  194. if ((id = shmget (key, size, IPC_CREAT|0666)) < 0) {
  195. jack_error ("cannot create new port segment of %d bytes, key = 0x%x (%s)", size, key, strerror (errno));
  196. return -1;
  197. }
  198. if ((addr = shmat (id, 0, 0)) == (char *) -1) {
  199. jack_error ("cannot attach new port segment (%s)", strerror (errno));
  200. shmctl (id, IPC_RMID, 0);
  201. return -1;
  202. }
  203. on_exit (shm_destroy, (void *) id);
  204. si = (jack_port_segment_info_t *) malloc (sizeof (jack_port_segment_info_t));
  205. si->shm_key = key;
  206. si->address = addr;
  207. engine->port_segments = g_slist_prepend (engine->port_segments, si);
  208. engine->port_segment_key = key; /* XXX fix me */
  209. engine->port_segment_address = addr; /* XXX fix me */
  210. pthread_mutex_lock (&engine->buffer_lock);
  211. offset = 0;
  212. step = engine->control->buffer_size * sizeof (sample_t);
  213. while (offset < size) {
  214. jack_port_buffer_info_t *bi;
  215. bi = (jack_port_buffer_info_t *) malloc (sizeof (jack_port_buffer_info_t));
  216. bi->shm_key = key;
  217. bi->offset = offset;
  218. /* we append because we want the list to be in memory-address order */
  219. engine->port_buffer_freelist = g_slist_append (engine->port_buffer_freelist, bi);
  220. offset += step;
  221. }
  222. /* convert the first chunk of the segment into a zero-filled area */
  223. if (engine->silent_buffer == 0) {
  224. engine->silent_buffer = (jack_port_buffer_info_t *) engine->port_buffer_freelist->data;
  225. engine->port_buffer_freelist = g_slist_remove_link (engine->port_buffer_freelist, engine->port_buffer_freelist);
  226. memset (engine->port_segment_address + engine->silent_buffer->offset, 0,
  227. sizeof (sample_t) * engine->control->buffer_size);
  228. }
  229. pthread_mutex_unlock (&engine->buffer_lock);
  230. /* XXX notify all clients of new segment */
  231. return 0;
  232. }
  233. static int
  234. jack_set_buffer_size (jack_engine_t *engine, nframes_t nframes)
  235. {
  236. /* XXX this is not really right, since it only works for
  237. audio ports.
  238. */
  239. engine->control->buffer_size = nframes;
  240. jack_add_port_segment (engine, engine->control->port_max);
  241. return 0;
  242. }
  243. static int
  244. jack_set_sample_rate (jack_engine_t *engine, nframes_t nframes)
  245. {
  246. engine->control->sample_rate = nframes;
  247. return 0;
  248. }
  249. static int
  250. jack_process (jack_engine_t *engine, nframes_t nframes)
  251. {
  252. int err = 0;
  253. jack_client_internal_t *client;
  254. jack_client_control_t *ctl;
  255. GSList *node;
  256. struct pollfd pollfd[1];
  257. char c;
  258. unsigned long then, now;
  259. // rdtscl (then);
  260. if (pthread_mutex_trylock (&engine->graph_lock) != 0) {
  261. return 0;
  262. }
  263. for (node = engine->clients; node; node = g_slist_next (node)) {
  264. ctl = ((jack_client_internal_t *) node->data)->control;
  265. ctl->state = JACK_CLIENT_STATE_NOT_TRIGGERED;
  266. ctl->nframes = nframes;
  267. }
  268. if (engine->timebase_client) {
  269. engine->control->frame_time = engine->timebase_client->control->frame_time;
  270. }
  271. for (node = engine->clients; err == 0 && node; ) {
  272. client = (jack_client_internal_t *) node->data;
  273. if (!client->control->active) {
  274. node = g_slist_next (node);
  275. continue;
  276. }
  277. ctl = client->control;
  278. if (jack_client_is_inprocess (client)) {
  279. /* in-process client ("plugin") */
  280. if (ctl->process (nframes, ctl->process_arg) == 0) {
  281. ctl->state = JACK_CLIENT_STATE_FINISHED;
  282. } else {
  283. jack_error ("in-process client %s failed", client->control->name);
  284. ctl->state = JACK_CLIENT_STATE_TRIGGERED;
  285. err++;
  286. break;
  287. }
  288. node = g_slist_next (node);
  289. } else {
  290. /* out of process subgraph */
  291. if (write (client->subgraph_start_fd, &c, sizeof (c)) != sizeof (c)) {
  292. jack_error ("cannot initiate graph processing (%s)", strerror (errno));
  293. err++;
  294. break;
  295. }
  296. /* now wait for the result. use poll instead of read so that we
  297. can timeout effectively.
  298. */
  299. pollfd[0].fd = client->subgraph_wait_fd;
  300. pollfd[0].events = POLLIN|POLLERR|POLLHUP|POLLNVAL;
  301. rdtscl (then);
  302. if (poll (pollfd, 1, engine->driver->period_interval) < 0) {
  303. jack_error ("engine cannot poll for graph completion (%s)", strerror (errno));
  304. err++;
  305. break;
  306. }
  307. rdtscl (now);
  308. if (pollfd[0].revents == 0) {
  309. jack_error ("subgraph starting at %s timed out (state = %d) (time = %f usecs)",
  310. client->control->name, client->control->state,
  311. ((float)(now - then))/450.0f);
  312. err++;
  313. break;
  314. } else if (pollfd[0].revents & ~POLLIN) {
  315. jack_error ("error/hangup on graph wait fd");
  316. err++;
  317. break;
  318. } else {
  319. if (read (client->subgraph_wait_fd, &c, sizeof (c)) != sizeof (c)) {
  320. jack_error ("cannot clean up byte from graph wait fd (%s)", strerror (errno));
  321. err++;
  322. break;
  323. }
  324. }
  325. /* Move to next in-process client (or end of client list) */
  326. while (node) {
  327. if (jack_client_is_inprocess (((jack_client_internal_t *) node->data))) {
  328. break;
  329. }
  330. node = g_slist_next (node);
  331. }
  332. }
  333. }
  334. pthread_mutex_unlock (&engine->graph_lock);
  335. if (err) {
  336. jack_cleanup_clients (engine);
  337. }
  338. // rdtscl (now);
  339. // printf ("engine cycle time: %.6f usecs\n", ((float) (now - then)) / 450.00f);
  340. return 0;
  341. }
  342. static int
  343. jack_load_client (jack_engine_t *engine, jack_client_internal_t *client, const char *path_to_so)
  344. {
  345. const char *errstr;
  346. dlhandle handle;
  347. handle = dlopen (path_to_so, RTLD_NOW|RTLD_GLOBAL);
  348. if (handle == 0) {
  349. if ((errstr = dlerror ()) != 0) {
  350. jack_error ("can't load \"%s\": %s", path_to_so, errstr);
  351. } else {
  352. jack_error ("bizarre error loading driver shared object %s", path_to_so);
  353. }
  354. return -1;
  355. }
  356. client->handle = handle;
  357. #if 0
  358. initialize = dlsym (handle, "client_initialize");
  359. if ((errstr = dlerror ()) != 0) {
  360. jack_error ("no initialize function in shared object %s\n", path_to_so);
  361. dlclose (handle);
  362. return -1;
  363. }
  364. finish = dlsym (handle, "client_finish");
  365. if ((errstr = dlerror ()) != 0) {
  366. jack_error ("no finish function in in shared driver object %s", path_to_so);
  367. dlclose (handle);
  368. return -1;
  369. }
  370. #endif
  371. return 0;
  372. }
  373. static void
  374. jack_client_unload (jack_client_internal_t *client)
  375. {
  376. if (client->handle) {
  377. // client->finish (client);
  378. dlclose (client->handle);
  379. }
  380. }
  381. static int
  382. handle_new_client (jack_engine_t *engine, int client_fd)
  383. {
  384. jack_client_internal_t *client;
  385. jack_client_connect_request_t req;
  386. jack_client_connect_result_t res;
  387. if (read (client_fd, &req, sizeof (req)) != sizeof (req)) {
  388. jack_error ("cannot read connection request from client");
  389. return -1;
  390. }
  391. res.status = 0;
  392. if ((client = jack_client_internal_new (engine, client_fd, &req)) == 0) {
  393. jack_error ("cannot create new client object");
  394. return -1;
  395. }
  396. printf ("new client: %s, type %d @ %p\n", client->control->name, req.type, client->control);
  397. res.status = 0;
  398. res.client_key = client->shm_key;
  399. res.control_key = engine->control_key;
  400. res.port_segment_key = engine->port_segment_key;
  401. res.realtime = engine->control->real_time;
  402. res.realtime_priority = engine->rtpriority - 1;
  403. if (jack_client_is_inprocess (client)) {
  404. res.client_control = client->control;
  405. res.engine_control = engine->control;
  406. } else {
  407. strcpy (res.fifo_prefix, engine->fifo_prefix);
  408. }
  409. res.status = 0;
  410. if (write (client->request_fd, &res, sizeof (res)) != sizeof (res)) {
  411. jack_error ("cannot write connection response to client");
  412. jack_client_delete (engine, client);
  413. return -1;
  414. }
  415. if (res.status) {
  416. return res.status;
  417. }
  418. pthread_mutex_lock (&engine->graph_lock);
  419. engine->clients = g_slist_prepend (engine->clients, client);
  420. pthread_mutex_unlock (&engine->graph_lock);
  421. if (client->control->type != ClientDynamic) {
  422. if (engine->pfd_max >= engine->pfd_size) {
  423. engine->pfd = (struct pollfd *) realloc (engine->pfd, sizeof (struct pollfd) * engine->pfd_size + 16);
  424. engine->pfd_size += 16;
  425. }
  426. engine->pfd[engine->pfd_max].fd = client->request_fd;
  427. engine->pfd[engine->pfd_max].events = POLLIN|POLLPRI|POLLERR|POLLHUP|POLLNVAL;
  428. engine->pfd_max++;
  429. }
  430. return 0;
  431. }
  432. static int
  433. handle_client_ack_connection (jack_engine_t *engine, int client_fd)
  434. {
  435. jack_client_internal_t *client;
  436. jack_client_connect_ack_request_t req;
  437. jack_client_connect_ack_result_t res;
  438. if (read (client_fd, &req, sizeof (req)) != sizeof (req)) {
  439. jack_error ("cannot read ACK connection request from client");
  440. return -1;
  441. }
  442. if ((client = jack_client_internal_by_id (engine, req.client_id)) == NULL) {
  443. jack_error ("unknown client ID in ACK connection request");
  444. return -1;
  445. }
  446. fprintf (stderr, "client %s is on event fd %d\n", client->control->name, client_fd);
  447. client->event_fd = client_fd;
  448. res.status = 0;
  449. if (write (client->event_fd, &res, sizeof (res)) != sizeof (res)) {
  450. jack_error ("cannot write ACK connection response to client");
  451. return -1;
  452. }
  453. return 0;
  454. }
  455. static int
  456. jack_client_drop (jack_engine_t *engine, jack_client_id_t id)
  457. {
  458. jack_client_internal_t *client;
  459. if ((client = jack_client_internal_by_id (engine, id)) == 0) {
  460. jack_error ("unknown client ID in DropClient request");
  461. return -1;
  462. }
  463. jack_remove_client (engine, client);
  464. return 0;
  465. }
  466. #if 0
  467. static int
  468. jack_client_has_connections (jack_client_internal_t *client)
  469. {
  470. GSList *node;
  471. for (node = client->ports; node; node = g_slist_next (node)) {
  472. if (((jack_port_internal_t *) node->data)->connections) {
  473. return TRUE;
  474. }
  475. }
  476. return FALSE;
  477. }
  478. #endif
  479. static int
  480. jack_client_activate (jack_engine_t *engine, jack_client_id_t id)
  481. {
  482. jack_client_internal_t *client;
  483. GSList *node;
  484. int ret = -1;
  485. pthread_mutex_lock (&engine->graph_lock);
  486. for (node = engine->clients; node; node = g_slist_next (node)) {
  487. if (((jack_client_internal_t *) node->data)->control->id == id) {
  488. client = (jack_client_internal_t *) node->data;
  489. client->control->active = TRUE;
  490. /* we call thus to make sure the FIFO is built by the time
  491. the client needs it. we don't care about the return
  492. value at this point.
  493. */
  494. jack_get_fifo_fd (engine, ++engine->external_client_cnt);
  495. jack_rechain_graph (engine, FALSE);
  496. ret = 0;
  497. break;
  498. }
  499. }
  500. pthread_mutex_unlock (&engine->graph_lock);
  501. return ret;
  502. }
  503. static int
  504. jack_client_do_deactivate (jack_engine_t *engine, jack_client_internal_t *client)
  505. {
  506. /* called must hold engine->graph_lock and must have checked for and/or
  507. cleared all connections held by client.
  508. */
  509. client->control->active = FALSE;
  510. if (!jack_client_is_inprocess (client)) {
  511. engine->external_client_cnt--;
  512. }
  513. jack_sort_graph (engine, FALSE);
  514. return 0;
  515. }
  516. static void
  517. jack_client_disconnect (jack_engine_t *engine, jack_client_internal_t *client)
  518. {
  519. GSList *node;
  520. jack_port_internal_t *port;
  521. /* call tree **** MUST HOLD *** engine->graph_lock */
  522. for (node = client->ports; node; node = g_slist_next (node)) {
  523. port = (jack_port_internal_t *) node->data;
  524. jack_port_clear_connections (engine, port);
  525. jack_port_release (engine, port);
  526. }
  527. g_slist_free (client->ports);
  528. g_slist_free (client->fed_by);
  529. client->fed_by = 0;
  530. client->ports = 0;
  531. }
  532. static int
  533. jack_client_deactivate (jack_engine_t *engine, jack_client_id_t id, int to_wait)
  534. {
  535. GSList *node;
  536. int ret = -1;
  537. pthread_mutex_lock (&engine->graph_lock);
  538. for (node = engine->clients; node; node = g_slist_next (node)) {
  539. jack_client_internal_t *client = (jack_client_internal_t *) node->data;
  540. if (client->control->id == id) {
  541. GSList *portnode;
  542. jack_port_internal_t *port;
  543. if (client == engine->timebase_client) {
  544. engine->timebase_client = 0;
  545. engine->control->frame_time = 0;
  546. }
  547. for (portnode = client->ports; portnode; portnode = g_slist_next (portnode)) {
  548. port = (jack_port_internal_t *) portnode->data;
  549. jack_port_clear_connections (engine, port);
  550. }
  551. ret = jack_client_do_deactivate (engine, node->data);
  552. break;
  553. }
  554. }
  555. pthread_mutex_unlock (&engine->graph_lock);
  556. return ret;
  557. }
  558. static int
  559. jack_set_timebase (jack_engine_t *engine, jack_client_id_t client)
  560. {
  561. int ret = -1;
  562. pthread_mutex_lock (&engine->graph_lock);
  563. if ((engine->timebase_client = jack_client_internal_by_id (engine, client)) != 0) {
  564. engine->control->frame_time = engine->timebase_client->control->frame_time;
  565. ret = 0;
  566. }
  567. pthread_mutex_unlock (&engine->graph_lock);
  568. return ret;
  569. }
  570. static int
  571. handle_client_jack_error (jack_engine_t *engine, int fd)
  572. {
  573. jack_client_internal_t *client = 0;
  574. GSList *node;
  575. pthread_mutex_lock (&engine->graph_lock);
  576. for (node = engine->clients; node; node = g_slist_next (node)) {
  577. if (((jack_client_internal_t *) node->data)->request_fd == fd) {
  578. client = (jack_client_internal_t *) node->data;
  579. break;
  580. }
  581. }
  582. pthread_mutex_unlock (&engine->graph_lock);
  583. if (client == 0) {
  584. jack_error ("i/o error on unknown client fd %d", fd);
  585. return -1;
  586. }
  587. jack_remove_client (engine, client);
  588. return 0;
  589. }
  590. static int
  591. jack_client_port_monitor (jack_engine_t *engine, jack_port_id_t port_id, int onoff)
  592. {
  593. jack_port_shared_t *port;
  594. jack_client_internal_t *client = NULL;
  595. jack_event_t event;
  596. if (port_id < 0 || port_id >= engine->port_max) {
  597. jack_error ("illegal port ID in port monitor request");
  598. return -1;
  599. }
  600. port = &engine->control->ports[port_id];
  601. if (!(port->flags & JackPortCanMonitor)) {
  602. jack_error ("port monitor request made on a port (%s) that doesn't support monitoring",
  603. port->name);
  604. return -1;
  605. }
  606. pthread_mutex_lock (&engine->graph_lock);
  607. if ((client = jack_client_internal_by_id (engine, port->client_id)) == NULL) {
  608. jack_error ("unknown client owns port %d!!", port_id);
  609. pthread_mutex_unlock (&engine->graph_lock);
  610. return -1;
  611. }
  612. pthread_mutex_unlock (&engine->graph_lock);
  613. event.type = (onoff ? PortMonitor : PortUnMonitor);
  614. event.x.port_id = port_id;
  615. return jack_deliver_event (engine, client, &event);
  616. }
  617. static int
  618. handle_client_io (jack_engine_t *engine, int fd)
  619. {
  620. jack_request_t req;
  621. jack_client_internal_t *client = 0;
  622. int reply_fd;
  623. GSList *node;
  624. pthread_mutex_lock (&engine->graph_lock);
  625. for (node = engine->clients; node; node = g_slist_next (node)) {
  626. if (((jack_client_internal_t *) node->data)->request_fd == fd) {
  627. client = (jack_client_internal_t *) node->data;
  628. break;
  629. }
  630. }
  631. pthread_mutex_unlock (&engine->graph_lock);
  632. if (client == 0) {
  633. jack_error ("client input on unknown fd %d!", fd);
  634. return -1;
  635. }
  636. if (read (client->request_fd, &req, sizeof (req)) < sizeof (req)) {
  637. jack_error ("cannot read request from client");
  638. jack_remove_client (engine, client);
  639. return -1;
  640. }
  641. reply_fd = client->request_fd;
  642. switch (req.type) {
  643. case RegisterPort:
  644. req.status = jack_port_do_register (engine, &req);
  645. break;
  646. case UnRegisterPort:
  647. req.status = jack_port_do_unregister (engine, &req);
  648. break;
  649. case ConnectPorts:
  650. req.status = jack_port_do_connect (engine, req.x.connect.source_port, req.x.connect.destination_port);
  651. break;
  652. case DisconnectPorts:
  653. req.status = jack_port_do_disconnect (engine, req.x.connect.source_port, req.x.connect.destination_port);
  654. break;
  655. case DropClient:
  656. req.status = jack_client_drop (engine, req.x.client_id);
  657. reply_fd = -1;
  658. break;
  659. case ActivateClient:
  660. req.status = jack_client_activate (engine, req.x.client_id);
  661. break;
  662. case DeactivateClient:
  663. req.status = jack_client_deactivate (engine, req.x.client_id, TRUE);
  664. break;
  665. case SetTimeBaseClient:
  666. req.status = jack_set_timebase (engine, req.x.client_id);
  667. break;
  668. case RequestPortMonitor:
  669. req.status = jack_client_port_monitor (engine, req.x.port_info.port_id, TRUE);
  670. break;
  671. case RequestPortUnMonitor:
  672. req.status = jack_client_port_monitor (engine, req.x.port_info.port_id, FALSE);
  673. break;
  674. }
  675. if (reply_fd >= 0) {
  676. if (write (reply_fd, &req, sizeof (req)) < sizeof (req)) {
  677. jack_error ("cannot write request result to client");
  678. return -1;
  679. }
  680. }
  681. return 0;
  682. }
  683. static void *
  684. jack_server_thread (void *arg)
  685. {
  686. jack_engine_t *engine = (jack_engine_t *) arg;
  687. struct sockaddr_un client_addr;
  688. socklen_t client_addrlen;
  689. struct pollfd *pfd;
  690. int client_socket;
  691. int done = 0;
  692. int i;
  693. int max;
  694. pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
  695. engine->pfd[0].fd = engine->fds[0];
  696. engine->pfd[0].events = POLLIN|POLLERR;
  697. engine->pfd[1].fd = engine->fds[1];
  698. engine->pfd[1].events = POLLIN|POLLERR;
  699. engine->pfd_max = 2;
  700. while (!done) {
  701. /* XXX race here with new external clients
  702. causing engine->pfd to be reallocated.
  703. I don't know how to solve this
  704. short of copying the entire
  705. contents of the pfd struct. Ick.
  706. */
  707. max = engine->pfd_max;
  708. pfd = engine->pfd;
  709. if (poll (pfd, max, 10000) < 0) {
  710. if (errno == EINTR) {
  711. continue;
  712. }
  713. jack_error ("poll failed (%s)", strerror (errno));
  714. break;
  715. }
  716. /* check the master server socket */
  717. if (pfd[0].revents & POLLERR) {
  718. jack_error ("error on server socket");
  719. break;
  720. }
  721. if (pfd[0].revents & POLLIN) {
  722. memset (&client_addr, 0, sizeof (client_addr));
  723. client_addrlen = sizeof (client_addr);
  724. if ((client_socket = accept (engine->fds[0], (struct sockaddr *) &client_addr, &client_addrlen)) < 0) {
  725. jack_error ("cannot accept new connection (%s)", strerror (errno));
  726. } else if (handle_new_client (engine, client_socket) < 0) {
  727. jack_error ("cannot complete new client connection process");
  728. close (client_socket);
  729. }
  730. }
  731. /* check the ACK server socket */
  732. if (pfd[1].revents & POLLERR) {
  733. jack_error ("error on server ACK socket");
  734. break;
  735. }
  736. if (pfd[1].revents & POLLIN) {
  737. memset (&client_addr, 0, sizeof (client_addr));
  738. client_addrlen = sizeof (client_addr);
  739. if ((client_socket = accept (engine->fds[1], (struct sockaddr *) &client_addr, &client_addrlen)) < 0) {
  740. jack_error ("cannot accept new ACK connection (%s)", strerror (errno));
  741. } else if (handle_client_ack_connection (engine, client_socket)) {
  742. jack_error ("cannot complete client ACK connection process");
  743. close (client_socket);
  744. }
  745. }
  746. /* check each client socket */
  747. for (i = 2; i < max; i++) {
  748. if (pfd[i].fd < 0) {
  749. continue;
  750. }
  751. if (pfd[i].revents & ~POLLIN) {
  752. handle_client_jack_error (engine, pfd[i].fd);
  753. } else if (pfd[i].revents & POLLIN) {
  754. if (handle_client_io (engine, pfd[i].fd)) {
  755. jack_error ("bad hci\n");
  756. }
  757. }
  758. }
  759. }
  760. return 0;
  761. }
  762. static void
  763. jack_start_server (jack_engine_t *engine)
  764. {
  765. pthread_create (&engine->server_thread, 0, &jack_server_thread, engine);
  766. pthread_detach (engine->server_thread);
  767. }
  768. jack_engine_t *
  769. jack_engine_new (int realtime, int rtpriority)
  770. {
  771. jack_engine_t *engine;
  772. size_t control_size;
  773. void *addr;
  774. int i;
  775. engine = (jack_engine_t *) malloc (sizeof (jack_engine_t));
  776. engine->driver = 0;
  777. engine->process = jack_process;
  778. engine->set_sample_rate = jack_set_sample_rate;
  779. engine->set_buffer_size = jack_set_buffer_size;
  780. engine->next_client_id = 1;
  781. engine->timebase_client = 0;
  782. engine->port_max = 128;
  783. engine->rtpriority = rtpriority;
  784. engine->silent_buffer = 0;
  785. engine->getthehelloutathere = FALSE;
  786. pthread_mutex_init (&engine->graph_lock, 0);
  787. pthread_mutex_init (&engine->buffer_lock, 0);
  788. pthread_mutex_init (&engine->port_lock, 0);
  789. engine->clients = 0;
  790. engine->port_segments = 0;
  791. engine->port_buffer_freelist = 0;
  792. engine->pfd_size = 16;
  793. engine->pfd_max = 0;
  794. engine->pfd = (struct pollfd *) malloc (sizeof (struct pollfd) * engine->pfd_size);
  795. engine->fifo_size = 16;
  796. engine->fifo = (int *) malloc (sizeof (int) * engine->fifo_size);
  797. for (i = 0; i < engine->fifo_size; i++) {
  798. engine->fifo[i] = -1;
  799. }
  800. /* Build a linked list of known port types. We use a list so that
  801. we can easily manage other data types without messing with
  802. reallocation of arrays, etc.
  803. */
  804. engine->port_types = NULL;
  805. for (i = 0; builtin_port_types[i].type_name; i++) {
  806. engine->port_types = g_slist_append (engine->port_types, &builtin_port_types[i]);
  807. }
  808. engine->external_client_cnt = 0;
  809. srandom (time ((time_t *) 0));
  810. engine->control_key = random();
  811. control_size = sizeof (jack_control_t) + (sizeof (jack_port_shared_t) * engine->port_max);
  812. if ((engine->control_shm_id = shmget (engine->control_key, control_size, IPC_CREAT|0644)) < 0) {
  813. jack_error ("cannot create engine control shared memory segment (%s)", strerror (errno));
  814. return 0;
  815. }
  816. if ((addr = shmat (engine->control_shm_id, 0, 0)) == (void *) -1) {
  817. jack_error ("cannot attach control shared memory segment (%s)", strerror (errno));
  818. shmctl (engine->control_shm_id, IPC_RMID, 0);
  819. return 0;
  820. }
  821. on_exit (shm_destroy, (void *) engine->control_shm_id);
  822. engine->control = (jack_control_t *) addr;
  823. /* Mark all ports as available */
  824. for (i = 0; i < engine->port_max; i++) {
  825. engine->control->ports[i].in_use = 0;
  826. engine->control->ports[i].id = i;
  827. }
  828. /* allocate internal port structures so that we can keep
  829. track of port connections.
  830. */
  831. engine->internal_ports = (jack_port_internal_t *) malloc (sizeof (jack_port_internal_t) * engine->port_max);
  832. for (i = 0; i < engine->port_max; i++) {
  833. engine->internal_ports[i].connections = 0;
  834. }
  835. if (make_sockets (engine->fds) < 0) {
  836. jack_error ("cannot create server sockets");
  837. return 0;
  838. }
  839. engine->control->port_max = engine->port_max;
  840. engine->control->real_time = realtime;
  841. engine->control->client_priority = engine->rtpriority - 1;
  842. engine->control->sample_rate = 0;
  843. engine->control->buffer_size = 0;
  844. engine->control->frame_time = 0;
  845. sprintf (engine->fifo_prefix, "/tmp/jack_fifo_%d", getpid());
  846. (void) jack_get_fifo_fd (engine, 0);
  847. jack_start_server (engine);
  848. return engine;
  849. }
  850. static int
  851. jack_become_real_time (pthread_t thread, int priority)
  852. {
  853. struct sched_param rtparam;
  854. int x;
  855. memset (&rtparam, 0, sizeof (rtparam));
  856. rtparam.sched_priority = priority;
  857. if ((x = pthread_setschedparam (thread, SCHED_FIFO, &rtparam)) != 0) {
  858. jack_error ("cannot set thread to real-time priority (FIFO/%d) (%d: %s)", rtparam.sched_priority, x, strerror (errno));
  859. }
  860. if (mlockall (MCL_CURRENT | MCL_FUTURE) != 0) {
  861. jack_error ("cannot lock down memory for RT thread (%s)", strerror (errno));
  862. }
  863. return 0;
  864. }
  865. void
  866. cancel_cleanup1 (void *arg)
  867. {
  868. jack_engine_t *engine = (jack_engine_t *) arg;
  869. printf ("audio thread cancelled or finished\n");
  870. engine->driver->audio_stop (engine->driver);
  871. }
  872. void
  873. cancel_cleanup2 (int status, void *arg)
  874. {
  875. jack_engine_t *engine = (jack_engine_t *) arg;
  876. engine->driver->audio_stop (engine->driver);
  877. engine->driver->finish (engine->driver);
  878. }
  879. static void *
  880. jack_main_thread (void *arg)
  881. {
  882. jack_engine_t *engine = (jack_engine_t *) arg;
  883. jack_driver_t *driver = engine->driver;
  884. // unsigned long start, end;
  885. if (engine->control->real_time) {
  886. jack_become_real_time (pthread_self(), engine->rtpriority);
  887. }
  888. pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
  889. on_exit (cancel_cleanup2, engine);
  890. if (driver->audio_start (driver)) {
  891. jack_error ("cannot start driver");
  892. pthread_exit (0);
  893. }
  894. while (1) {
  895. // start = end;
  896. if (driver->wait (driver)) {
  897. break;
  898. }
  899. // rdtscl (end);
  900. // printf ("driver cycle time: %.6f usecs\n", ((float) (end - start)) / 450.00f);
  901. }
  902. pthread_exit (0);
  903. }
  904. int
  905. jack_run (jack_engine_t *engine)
  906. {
  907. if (engine->driver == 0) {
  908. jack_error ("engine driver not set; cannot start");
  909. return -1;
  910. }
  911. return pthread_create (&engine->main_thread, 0, jack_main_thread, engine);
  912. }
  913. int
  914. jack_wait (jack_engine_t *engine)
  915. {
  916. void *ret = 0;
  917. int err;
  918. if ((err = pthread_join (engine->main_thread, &ret)) != 0) {
  919. switch (err) {
  920. case EINVAL:
  921. jack_error ("cannot join with audio thread (thread detached, or another thread is waiting)");
  922. break;
  923. case ESRCH:
  924. jack_error ("cannot join with audio thread (thread no longer exists)");
  925. break;
  926. case EDEADLK:
  927. jack_error ("programming error: jack_wait() called by audio thread");
  928. break;
  929. default:
  930. jack_error ("cannot join with audio thread (%s)", strerror (errno));
  931. }
  932. }
  933. return (int) ret;
  934. }
  935. int
  936. jack_engine_delete (jack_engine_t *engine)
  937. {
  938. pthread_cancel (engine->main_thread);
  939. return 0;
  940. }
  941. static jack_client_internal_t *
  942. jack_client_internal_new (jack_engine_t *engine, int fd, jack_client_connect_request_t *req)
  943. {
  944. jack_client_internal_t *client;
  945. key_t shm_key = 0;
  946. int shm_id = 0;
  947. void *addr = 0;
  948. switch (req->type) {
  949. case ClientDynamic:
  950. case ClientDriver:
  951. break;
  952. case ClientOutOfProcess:
  953. shm_key = random();
  954. if ((shm_id = shmget (shm_key, sizeof (jack_client_control_t), IPC_CREAT|0666)) < 0) {
  955. jack_error ("cannot create client control block");
  956. return 0;
  957. }
  958. if ((addr = shmat (shm_id, 0, 0)) == (void *) -1) {
  959. jack_error ("cannot attach new client control block");
  960. shmctl (shm_id, IPC_RMID, 0);
  961. return 0;
  962. }
  963. break;
  964. }
  965. client = (jack_client_internal_t *) malloc (sizeof (jack_client_internal_t));
  966. client->request_fd = fd;
  967. client->event_fd = -1;
  968. client->ports = 0;
  969. client->fed_by = 0;
  970. client->rank = UINT_MAX;
  971. client->next_client = NULL;
  972. client->handle = NULL;
  973. if (req->type != ClientOutOfProcess) {
  974. client->control = (jack_client_control_t *) malloc (sizeof (jack_client_control_t));
  975. } else {
  976. client->shm_id = shm_id;
  977. client->shm_key = shm_key;
  978. client->control = (jack_client_control_t *) addr;
  979. }
  980. client->control->type = req->type;
  981. client->control->active = FALSE;
  982. client->control->dead = FALSE;
  983. client->control->id = engine->next_client_id++;
  984. strcpy ((char *) client->control->name, req->name);
  985. client->control->process = NULL;
  986. client->control->process_arg = NULL;
  987. client->control->bufsize = NULL;
  988. client->control->bufsize_arg = NULL;
  989. client->control->srate = NULL;
  990. client->control->srate_arg = NULL;
  991. client->control->port_register = NULL;
  992. client->control->port_register_arg = NULL;
  993. client->control->port_monitor = NULL;
  994. client->control->port_monitor_arg = NULL;
  995. if (req->type == ClientDynamic) {
  996. if (jack_load_client (engine, client, req->object_path)) {
  997. jack_error ("cannot dynamically load client from \"%s\"", req->object_path);
  998. jack_client_delete (engine, client);
  999. return 0;
  1000. }
  1001. }
  1002. return client;
  1003. }
  1004. static void
  1005. jack_port_clear_connections (jack_engine_t *engine, jack_port_internal_t *port)
  1006. {
  1007. GSList *node, *next;
  1008. for (node = port->connections; node; ) {
  1009. next = g_slist_next (node);
  1010. jack_port_disconnect_internal (engine,
  1011. ((jack_connection_internal_t *) node->data)->source,
  1012. ((jack_connection_internal_t *) node->data)->destination,
  1013. FALSE);
  1014. node = next;
  1015. }
  1016. g_slist_free (port->connections);
  1017. port->connections = 0;
  1018. }
  1019. static void
  1020. jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client)
  1021. {
  1022. GSList *node;
  1023. int i;
  1024. printf ("removing client %s\n", client->control->name);
  1025. pthread_mutex_lock (&engine->graph_lock);
  1026. client->control->dead = TRUE;
  1027. if (client == engine->timebase_client) {
  1028. engine->timebase_client = 0;
  1029. engine->control->frame_time = 0;
  1030. }
  1031. jack_client_disconnect (engine, client);
  1032. for (node = engine->clients; node; node = g_slist_next (node)) {
  1033. if (((jack_client_internal_t *) node->data)->control->id == client->control->id) {
  1034. engine->clients = g_slist_remove_link (engine->clients, node);
  1035. g_slist_free_1 (node);
  1036. break;
  1037. }
  1038. }
  1039. jack_client_do_deactivate (engine, client);
  1040. /* rearrange the pollfd array so that things work right the
  1041. next time we go into poll(2).
  1042. */
  1043. for (i = 0; i < engine->pfd_max; i++) {
  1044. if (engine->pfd[i].fd == client->request_fd) {
  1045. if (i+1 < engine->pfd_max) {
  1046. memmove (&engine->pfd[i], &engine->pfd[i+1], sizeof (struct pollfd) * (engine->pfd_max - i));
  1047. }
  1048. engine->pfd_max--;
  1049. }
  1050. }
  1051. close (client->event_fd);
  1052. close (client->request_fd);
  1053. jack_client_delete (engine, client);
  1054. pthread_mutex_unlock (&engine->graph_lock);
  1055. }
  1056. static void
  1057. jack_client_delete (jack_engine_t *engine, jack_client_internal_t *client)
  1058. {
  1059. jack_client_disconnect (engine, client);
  1060. if (jack_client_is_inprocess (client)) {
  1061. jack_client_unload (client);
  1062. free ((char *) client->control);
  1063. } else {
  1064. shmdt ((void *) client->control);
  1065. }
  1066. free (client);
  1067. }
  1068. jack_client_internal_t *
  1069. jack_client_by_name (jack_engine_t *engine, const char *name)
  1070. {
  1071. jack_client_internal_t *client = NULL;
  1072. GSList *node;
  1073. pthread_mutex_lock (&engine->graph_lock);
  1074. for (node = engine->clients; node; node = g_slist_next (node)) {
  1075. if (strcmp ((const char *) ((jack_client_internal_t *) node->data)->control->name, name) == 0) {
  1076. client = (jack_client_internal_t *) node->data;
  1077. break;
  1078. }
  1079. }
  1080. pthread_mutex_unlock (&engine->graph_lock);
  1081. return client;
  1082. }
  1083. jack_client_internal_t *
  1084. jack_client_internal_by_id (jack_engine_t *engine, jack_client_id_t id)
  1085. {
  1086. jack_client_internal_t *client = NULL;
  1087. GSList *node;
  1088. /* call tree ***MUST HOLD*** engine->graph_lock */
  1089. for (node = engine->clients; node; node = g_slist_next (node)) {
  1090. if (((jack_client_internal_t *) node->data)->control->id == id) {
  1091. client = (jack_client_internal_t *) node->data;
  1092. break;
  1093. }
  1094. }
  1095. return client;
  1096. }
  1097. static int
  1098. jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, jack_event_t *event)
  1099. {
  1100. char status;
  1101. if (client->control->dead) {
  1102. return 0;
  1103. }
  1104. if (jack_client_is_inprocess (client)) {
  1105. switch (event->type) {
  1106. case PortConnected:
  1107. case PortDisconnected:
  1108. jack_client_handle_port_connection (client->control->private_internal_client, event);
  1109. break;
  1110. case GraphReordered:
  1111. jack_error ("reorder event delivered to internal client!");
  1112. break;
  1113. case BufferSizeChange:
  1114. if (client->control->bufsize) {
  1115. client->control->bufsize (event->x.n, client->control->bufsize_arg);
  1116. }
  1117. break;
  1118. case SampleRateChange:
  1119. if (client->control->srate) {
  1120. client->control->srate (event->x.n, client->control->bufsize_arg);
  1121. }
  1122. break;
  1123. case PortMonitor:
  1124. if (client->control->port_monitor) {
  1125. client->control->port_monitor (event->x.port_id, TRUE, client->control->port_monitor_arg);
  1126. }
  1127. break;
  1128. case PortUnMonitor:
  1129. if (client->control->port_monitor) {
  1130. client->control->port_monitor (event->x.port_id, FALSE, client->control->port_monitor_arg);
  1131. }
  1132. break;
  1133. default:
  1134. /* internal clients don't need to know */
  1135. break;
  1136. }
  1137. } else {
  1138. if (write (client->event_fd, event, sizeof (*event)) != sizeof (*event)) {
  1139. jack_error ("cannot send event to client [%s] (%s)", client->control->name, strerror (errno));
  1140. return -1;
  1141. }
  1142. if (read (client->event_fd, &status, sizeof (status)) != sizeof (status)) {
  1143. jack_error ("cannot read event response from client [%s] (%s)", client->control->name, strerror (errno));
  1144. return -1;
  1145. }
  1146. }
  1147. return 0;
  1148. }
  1149. int
  1150. jack_client_set_order (jack_engine_t *engine, jack_client_internal_t *client)
  1151. {
  1152. jack_event_t event;
  1153. event.type = GraphReordered;
  1154. event.x.n = client->rank;
  1155. return jack_deliver_event (engine, client, &event);
  1156. }
  1157. int
  1158. jack_rechain_graph (jack_engine_t *engine, int take_lock)
  1159. {
  1160. GSList *node, *next;
  1161. unsigned long n;
  1162. int err = 0;
  1163. int need_to_reset_fifo;
  1164. jack_client_internal_t *client, *subgraph_client, *next_client;
  1165. if (take_lock) {
  1166. pthread_mutex_lock (&engine->graph_lock);
  1167. }
  1168. /* We're going to try to avoid reconnecting clients that
  1169. don't need to be reconnected. This is slightly tricky,
  1170. but worth it for performance reasons.
  1171. */
  1172. subgraph_client = 0;
  1173. n = 0;
  1174. for (n = 0, node = engine->clients, next = NULL; node; node = next) {
  1175. next = g_slist_next (node);
  1176. if (((jack_client_internal_t *) node->data)->control->active) {
  1177. client = (jack_client_internal_t *) node->data;
  1178. /* find the next active client. its ok for this to be NULL */
  1179. while (next) {
  1180. if (((jack_client_internal_t *) next->data)->control->active) {
  1181. break;
  1182. }
  1183. next = g_slist_next (next);
  1184. };
  1185. if (next == NULL) {
  1186. next_client = NULL;
  1187. } else {
  1188. next_client = (jack_client_internal_t *) next->data;
  1189. }
  1190. if (client->rank != n || client->next_client != next_client) {
  1191. client->rank = n;
  1192. client->next_client = next_client;
  1193. need_to_reset_fifo = TRUE;
  1194. } else {
  1195. need_to_reset_fifo = FALSE;
  1196. }
  1197. if (jack_client_is_inprocess (client)) {
  1198. /* break the chain for the current subgraph. the server
  1199. will wait for chain on the nth FIFO, and will
  1200. then execute this in-process client.
  1201. */
  1202. if (subgraph_client) {
  1203. subgraph_client->subgraph_wait_fd = jack_get_fifo_fd (engine, n);
  1204. }
  1205. subgraph_client = 0;
  1206. } else {
  1207. if (subgraph_client == 0) {
  1208. /* start a new subgraph. the engine will start the chain
  1209. by writing to the nth FIFO.
  1210. */
  1211. subgraph_client = client;
  1212. subgraph_client->subgraph_start_fd = jack_get_fifo_fd (engine, n);
  1213. }
  1214. if (need_to_reset_fifo) {
  1215. jack_client_set_order (engine, client);
  1216. }
  1217. n++;
  1218. }
  1219. }
  1220. };
  1221. if (subgraph_client) {
  1222. subgraph_client->subgraph_wait_fd = jack_get_fifo_fd (engine, n);
  1223. }
  1224. if (take_lock) {
  1225. pthread_mutex_unlock (&engine->graph_lock);
  1226. }
  1227. return err;
  1228. }
  1229. static void
  1230. jack_trace_terminal (jack_client_internal_t *c1, jack_client_internal_t *rbase)
  1231. {
  1232. jack_client_internal_t *c2;
  1233. /* make a copy of the existing list of routes that feed c1 */
  1234. GSList *existing;
  1235. GSList *node;
  1236. if (c1->fed_by == 0) {
  1237. return;
  1238. }
  1239. existing = g_slist_copy (c1->fed_by);
  1240. /* for each route that feeds c1, recurse, marking it as feeding
  1241. rbase as well.
  1242. */
  1243. for (node = existing; node; node = g_slist_next (node)) {
  1244. c2 = (jack_client_internal_t *) node->data;
  1245. /* c2 is a route that feeds c1 which somehow feeds base. mark
  1246. base as being fed by c2, but don't do it more than
  1247. once.
  1248. */
  1249. if (g_slist_find (rbase->fed_by, c2) != NULL) {
  1250. continue;
  1251. }
  1252. rbase->fed_by = g_slist_prepend (rbase->fed_by, c2);
  1253. if (c2 != rbase && c2 != c1) {
  1254. /* now recurse, so that we can mark base as being fed by
  1255. all routes that feed c2
  1256. */
  1257. jack_trace_terminal (c2, rbase);
  1258. }
  1259. }
  1260. }
  1261. static int
  1262. jack_client_sort (jack_client_internal_t *a, jack_client_internal_t *b)
  1263. {
  1264. /* the driver client always comes after everything else */
  1265. if (a->control->type == ClientDriver) {
  1266. return 1;
  1267. }
  1268. if (b->control->type == ClientDriver) {
  1269. return -1;
  1270. }
  1271. if (g_slist_find (a->fed_by, b)) {
  1272. /* a comes after b */
  1273. return 1;
  1274. } else if (g_slist_find (b->fed_by, a)) {
  1275. /* b comes after a */
  1276. return -1;
  1277. } else {
  1278. /* we don't care */
  1279. return 0;
  1280. }
  1281. }
  1282. static int
  1283. jack_client_feeds (jack_client_internal_t *might, jack_client_internal_t *target)
  1284. {
  1285. GSList *pnode, *cnode;
  1286. /* Check every port of `might' for an outbound connection to `target'
  1287. */
  1288. for (pnode = might->ports; pnode; pnode = g_slist_next (pnode)) {
  1289. jack_port_internal_t *port;
  1290. port = (jack_port_internal_t *) pnode->data;
  1291. for (cnode = port->connections; cnode; cnode = g_slist_next (cnode)) {
  1292. jack_connection_internal_t *c;
  1293. c = (jack_connection_internal_t *) cnode->data;
  1294. if (c->source->shared->client_id == might->control->id &&
  1295. c->destination->shared->client_id == target->control->id) {
  1296. return 1;
  1297. }
  1298. }
  1299. }
  1300. return 0;
  1301. }
  1302. static void
  1303. jack_sort_graph (jack_engine_t *engine, int take_lock)
  1304. {
  1305. GSList *node, *onode;
  1306. jack_client_internal_t *client;
  1307. jack_client_internal_t *oclient;
  1308. if (take_lock) {
  1309. pthread_mutex_lock (&engine->graph_lock);
  1310. }
  1311. for (node = engine->clients; node; node = g_slist_next (node)) {
  1312. client = (jack_client_internal_t *) node->data;
  1313. g_slist_free (client->fed_by);
  1314. client->fed_by = 0;
  1315. for (onode = engine->clients; onode; onode = g_slist_next (onode)) {
  1316. oclient = (jack_client_internal_t *) onode->data;
  1317. if (jack_client_feeds (oclient, client)) {
  1318. client->fed_by = g_slist_prepend (client->fed_by, oclient);
  1319. }
  1320. }
  1321. }
  1322. for (node = engine->clients; node; node = g_slist_next (node)) {
  1323. jack_trace_terminal ((jack_client_internal_t *) node->data,
  1324. (jack_client_internal_t *) node->data);
  1325. }
  1326. engine->clients = g_slist_sort (engine->clients, (GCompareFunc) jack_client_sort);
  1327. jack_rechain_graph (engine, FALSE);
  1328. if (take_lock) {
  1329. pthread_mutex_unlock (&engine->graph_lock);
  1330. }
  1331. }
  1332. static int
  1333. jack_port_do_connect (jack_engine_t *engine,
  1334. const char *source_port,
  1335. const char *destination_port)
  1336. {
  1337. jack_connection_internal_t *connection;
  1338. jack_port_internal_t *srcport, *dstport;
  1339. jack_port_id_t src_id, dst_id;
  1340. fprintf (stderr, "trying to connect %s and %s\n", source_port, destination_port);
  1341. if ((srcport = jack_get_port_by_name (engine, source_port)) == 0) {
  1342. jack_error ("unknown source port in attempted connection [%s]", source_port);
  1343. return -1;
  1344. }
  1345. if ((dstport = jack_get_port_by_name (engine, destination_port)) == 0) {
  1346. jack_error ("unknown destination port in attempted connection [%s]", destination_port);
  1347. return -1;
  1348. }
  1349. if ((dstport->shared->flags & JackPortIsInput) == 0) {
  1350. jack_error ("destination port in attempted connection is not an input port");
  1351. return -1;
  1352. }
  1353. if ((srcport->shared->flags & JackPortIsOutput) == 0) {
  1354. jack_error ("source port in attempted connection is not an output port");
  1355. return -1;
  1356. }
  1357. if (strcmp (srcport->shared->type_info.type_name,
  1358. dstport->shared->type_info.type_name) != 0) {
  1359. jack_error ("ports used in attemped connection are not of the same data type");
  1360. return -1;
  1361. }
  1362. connection = (jack_connection_internal_t *) malloc (sizeof (jack_connection_internal_t));
  1363. connection->source = srcport;
  1364. connection->destination = dstport;
  1365. src_id = srcport->shared->id;
  1366. dst_id = dstport->shared->id;
  1367. pthread_mutex_lock (&engine->graph_lock);
  1368. if (dstport->connections && dstport->shared->type_info.mixdown == NULL) {
  1369. jack_error ("cannot make multiple connections to a port of type [%s]", dstport->shared->type_info.type_name);
  1370. free (connection);
  1371. return -1;
  1372. } else {
  1373. dstport->connections = g_slist_prepend (dstport->connections, connection);
  1374. srcport->connections = g_slist_prepend (srcport->connections, connection);
  1375. jack_sort_graph (engine, FALSE);
  1376. jack_send_connection_notification (engine, srcport->shared->client_id, src_id, dst_id, TRUE);
  1377. jack_send_connection_notification (engine, dstport->shared->client_id, dst_id, src_id, TRUE);
  1378. }
  1379. pthread_mutex_unlock (&engine->graph_lock);
  1380. return 0;
  1381. }
  1382. int
  1383. jack_port_disconnect_internal (jack_engine_t *engine,
  1384. jack_port_internal_t *srcport,
  1385. jack_port_internal_t *dstport,
  1386. int sort_graph)
  1387. {
  1388. GSList *node;
  1389. jack_connection_internal_t *connect;
  1390. int ret = -1;
  1391. jack_port_id_t src_id, dst_id;
  1392. /* call tree **** MUST HOLD **** engine->graph_lock. */
  1393. printf ("disconnecting %s and %s\n", srcport->shared->name, dstport->shared->name);
  1394. for (node = srcport->connections; node; node = g_slist_next (node)) {
  1395. connect = (jack_connection_internal_t *) node->data;
  1396. if (connect->source == srcport && connect->destination == dstport) {
  1397. srcport->connections = g_slist_remove (srcport->connections, connect);
  1398. dstport->connections = g_slist_remove (dstport->connections, connect);
  1399. src_id = srcport->shared->id;
  1400. dst_id = dstport->shared->id;
  1401. jack_send_connection_notification (engine, srcport->shared->client_id, src_id, dst_id, FALSE);
  1402. jack_send_connection_notification (engine, dstport->shared->client_id, dst_id, src_id, FALSE);
  1403. free (connect);
  1404. ret = 0;
  1405. break;
  1406. }
  1407. }
  1408. if (sort_graph) {
  1409. jack_sort_graph (engine, FALSE);
  1410. }
  1411. if (ret == -1) {
  1412. printf ("disconnect failed\n");
  1413. }
  1414. return ret;
  1415. }
  1416. static int
  1417. jack_port_do_disconnect (jack_engine_t *engine,
  1418. const char *source_port,
  1419. const char *destination_port)
  1420. {
  1421. jack_port_internal_t *srcport, *dstport;
  1422. int ret = -1;
  1423. if ((srcport = jack_get_port_by_name (engine, source_port)) == 0) {
  1424. jack_error ("unknown source port in attempted connection [%s]", source_port);
  1425. return -1;
  1426. }
  1427. if ((dstport = jack_get_port_by_name (engine, destination_port)) == 0) {
  1428. jack_error ("unknown destination port in attempted connection [%s]", destination_port);
  1429. return -1;
  1430. }
  1431. pthread_mutex_lock (&engine->graph_lock);
  1432. ret = jack_port_disconnect_internal (engine, srcport, dstport, TRUE);
  1433. pthread_mutex_unlock (&engine->graph_lock);
  1434. return ret;
  1435. }
  1436. static int
  1437. jack_get_fifo_fd (jack_engine_t *engine, int which_fifo)
  1438. {
  1439. char path[FIFO_NAME_SIZE+1];
  1440. struct stat statbuf;
  1441. sprintf (path, "%s-%d", engine->fifo_prefix, which_fifo);
  1442. if (stat (path, &statbuf)) {
  1443. if (errno == ENOENT) {
  1444. if (mknod (path, 0666|S_IFIFO, 0) < 0) {
  1445. jack_error ("cannot create inter-client FIFO [%s] (%s)\n", path, strerror (errno));
  1446. return -1;
  1447. }
  1448. } else {
  1449. jack_error ("cannot check on FIFO %d\n", which_fifo);
  1450. return -1;
  1451. }
  1452. } else {
  1453. if (!S_ISFIFO(statbuf.st_mode)) {
  1454. jack_error ("FIFO %d (%s) already exists, but is not a FIFO!\n", which_fifo, path);
  1455. return -1;
  1456. }
  1457. }
  1458. if (which_fifo >= engine->fifo_size) {
  1459. int i;
  1460. engine->fifo = (int *) realloc (engine->fifo, sizeof (int) * engine->fifo_size + 16);
  1461. for (i = engine->fifo_size; i < engine->fifo_size + 16; i++) {
  1462. engine->fifo[i] = -1;
  1463. }
  1464. engine->fifo_size += 16;
  1465. }
  1466. if (engine->fifo[which_fifo] < 0) {
  1467. if ((engine->fifo[which_fifo] = open (path, O_RDWR|O_CREAT, 0666)) < 0) {
  1468. jack_error ("cannot open fifo [%s] (%s)", path, strerror (errno));
  1469. return -1;
  1470. }
  1471. }
  1472. return engine->fifo[which_fifo];
  1473. }
  1474. int
  1475. jack_use_driver (jack_engine_t *engine, jack_driver_t *driver)
  1476. {
  1477. if (engine->driver) {
  1478. engine->driver->detach (engine->driver, engine);
  1479. engine->driver = 0;
  1480. }
  1481. if (driver) {
  1482. if (driver->attach (driver, engine)) {
  1483. return -1;
  1484. }
  1485. }
  1486. engine->driver = driver;
  1487. return 0;
  1488. }
  1489. /* PORT RELATED FUNCTIONS */
  1490. jack_port_id_t
  1491. jack_get_free_port (jack_engine_t *engine)
  1492. {
  1493. jack_port_id_t i;
  1494. pthread_mutex_lock (&engine->port_lock);
  1495. for (i = 0; i < engine->port_max; i++) {
  1496. if (engine->control->ports[i].in_use == 0) {
  1497. engine->control->ports[i].in_use = 1;
  1498. break;
  1499. }
  1500. }
  1501. pthread_mutex_unlock (&engine->port_lock);
  1502. if (i == engine->port_max) {
  1503. return NoPort;
  1504. }
  1505. return i;
  1506. }
  1507. static void
  1508. jack_port_release (jack_engine_t *engine, jack_port_internal_t *port)
  1509. {
  1510. /* XXX add the buffer used by the port back the (correct) freelist */
  1511. pthread_mutex_lock (&engine->port_lock);
  1512. port->shared->in_use = 0;
  1513. pthread_mutex_unlock (&engine->port_lock);
  1514. }
  1515. jack_port_internal_t *
  1516. jack_get_port_internal_by_name (jack_engine_t *engine, const char *name)
  1517. {
  1518. jack_port_id_t id;
  1519. pthread_mutex_lock (&engine->port_lock);
  1520. for (id = 0; id < engine->port_max; id++) {
  1521. if (strcmp (engine->control->ports[id].name, name) == 0) {
  1522. break;
  1523. }
  1524. }
  1525. pthread_mutex_unlock (&engine->port_lock);
  1526. if (id != engine->port_max) {
  1527. return &engine->internal_ports[id];
  1528. } else {
  1529. return NULL;
  1530. }
  1531. }
  1532. int
  1533. jack_port_do_register (jack_engine_t *engine, jack_request_t *req)
  1534. {
  1535. GSList *node;
  1536. jack_port_id_t port_id;
  1537. jack_port_shared_t *shared;
  1538. jack_port_internal_t *port;
  1539. jack_client_internal_t *client;
  1540. jack_port_type_info_t *type_info;
  1541. pthread_mutex_lock (&engine->graph_lock);
  1542. if ((client = jack_client_internal_by_id (engine, req->x.port_info.client_id)) == 0) {
  1543. jack_error ("unknown client id in port registration request");
  1544. return -1;
  1545. }
  1546. pthread_mutex_unlock (&engine->graph_lock);
  1547. if ((port_id = jack_get_free_port (engine)) == NoPort) {
  1548. jack_error ("no ports available!");
  1549. return -1;
  1550. }
  1551. shared = &engine->control->ports[port_id];
  1552. strcpy (shared->name, req->x.port_info.name);
  1553. shared->client_id = req->x.port_info.client_id;
  1554. shared->flags = req->x.port_info.flags;
  1555. shared->locked = 0;
  1556. shared->buffer_size = req->x.port_info.buffer_size;
  1557. port = &engine->internal_ports[port_id];
  1558. port->shared = shared;
  1559. port->connections = 0;
  1560. type_info = NULL;
  1561. for (node = engine->port_types; node; node = g_slist_next (node)) {
  1562. if (strcmp (req->x.port_info.type, ((jack_port_type_info_t *) node->data)->type_name) == 0) {
  1563. type_info = (jack_port_type_info_t *) node->data;
  1564. break;
  1565. }
  1566. }
  1567. if (type_info == NULL) {
  1568. /* not a builtin type, so allocate a new type_info structure,
  1569. and fill it appropriately.
  1570. */
  1571. type_info = (jack_port_type_info_t *) malloc (sizeof (jack_port_type_info_t));
  1572. type_info->type_name = strdup (req->x.port_info.type);
  1573. type_info->mixdown = NULL; /* we have no idea how to mix this */
  1574. type_info->buffer_scale_factor = -1; /* use specified port buffer size */
  1575. engine->port_types = g_slist_prepend (engine->port_types, type_info);
  1576. }
  1577. memcpy (&port->shared->type_info, type_info, sizeof (jack_port_type_info_t));
  1578. if (jack_port_assign_buffer (engine, port)) {
  1579. jack_error ("cannot assign buffer for port");
  1580. return -1;
  1581. }
  1582. pthread_mutex_lock (&engine->graph_lock);
  1583. client->ports = g_slist_prepend (client->ports, port);
  1584. jack_port_registration_notify (engine, port_id, TRUE);
  1585. pthread_mutex_unlock (&engine->graph_lock);
  1586. req->x.port_info.port_id = port_id;
  1587. return 0;
  1588. }
  1589. int
  1590. jack_port_do_unregister (jack_engine_t *engine, jack_request_t *req)
  1591. {
  1592. jack_client_internal_t *client;
  1593. jack_port_shared_t *shared;
  1594. jack_port_internal_t *port;
  1595. if (req->x.port_info.port_id < 0 || req->x.port_info.port_id > engine->port_max) {
  1596. jack_error ("invalid port ID %d in unregister request\n", req->x.port_info.port_id);
  1597. return -1;
  1598. }
  1599. shared = &engine->control->ports[req->x.port_info.port_id];
  1600. pthread_mutex_lock (&engine->graph_lock);
  1601. if ((client = jack_client_internal_by_id (engine, shared->client_id)) == NULL) {
  1602. jack_error ("unknown client id in port registration request");
  1603. return -1;
  1604. }
  1605. pthread_mutex_unlock (&engine->graph_lock);
  1606. port = &engine->internal_ports[req->x.port_info.port_id];
  1607. jack_port_release (engine, &engine->internal_ports[req->x.port_info.port_id]);
  1608. pthread_mutex_lock (&engine->graph_lock);
  1609. client->ports = g_slist_remove (client->ports, port);
  1610. jack_port_registration_notify (engine, req->x.port_info.port_id, FALSE);
  1611. pthread_mutex_unlock (&engine->graph_lock);
  1612. return 0;
  1613. }
  1614. void
  1615. jack_port_registration_notify (jack_engine_t *engine, jack_port_id_t port_id, int yn)
  1616. {
  1617. jack_event_t event;
  1618. jack_client_internal_t *client;
  1619. GSList *node;
  1620. event.type = (yn ? PortRegistered : PortUnregistered);
  1621. event.x.port_id = port_id;
  1622. for (node = engine->clients; node; node = g_slist_next (node)) {
  1623. client = (jack_client_internal_t *) node->data;
  1624. if (!client->control->active) {
  1625. continue;
  1626. }
  1627. if (client->control->port_register) {
  1628. if (jack_deliver_event (engine, client, &event)) {
  1629. jack_error ("cannot send port registration notification to %s (%s)",
  1630. client->control->name, strerror (errno));
  1631. }
  1632. }
  1633. }
  1634. }
  1635. int
  1636. jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port)
  1637. {
  1638. GSList *node;
  1639. jack_port_segment_info_t *psi;
  1640. jack_port_buffer_info_t *bi;
  1641. port->shared->shm_key = -1;
  1642. if (port->shared->flags & JackPortIsInput) {
  1643. return 0;
  1644. }
  1645. pthread_mutex_lock (&engine->buffer_lock);
  1646. if (engine->port_buffer_freelist == NULL) {
  1647. jack_error ("no more buffers available!");
  1648. goto out;
  1649. }
  1650. bi = (jack_port_buffer_info_t *) engine->port_buffer_freelist->data;
  1651. for (node = engine->port_segments; node; node = g_slist_next (node)) {
  1652. psi = (jack_port_segment_info_t *) node->data;
  1653. if (bi->shm_key == psi->shm_key) {
  1654. port->shared->shm_key = psi->shm_key;
  1655. port->shared->offset = bi->offset;
  1656. break;
  1657. }
  1658. }
  1659. if (port->shared->shm_key >= 0) {
  1660. engine->port_buffer_freelist = g_slist_remove (engine->port_buffer_freelist, bi);
  1661. } else {
  1662. jack_error ("port segment info for 0x%x:%d not found!", bi->shm_key, bi->offset);
  1663. }
  1664. out:
  1665. pthread_mutex_unlock (&engine->buffer_lock);
  1666. if (port->shared->shm_key < 0) {
  1667. return -1;
  1668. } else {
  1669. return 0;
  1670. }
  1671. }
  1672. static jack_port_internal_t *
  1673. jack_get_port_by_name (jack_engine_t *engine, const char *name)
  1674. {
  1675. jack_port_id_t id;
  1676. /* Note the potential race on "in_use". Other design
  1677. elements prevent this from being a problem.
  1678. */
  1679. for (id = 0; id < engine->port_max; id++) {
  1680. if (engine->control->ports[id].in_use && strcmp (engine->control->ports[id].name, name) == 0) {
  1681. return &engine->internal_ports[id];
  1682. }
  1683. }
  1684. return NULL;
  1685. }
  1686. static int
  1687. jack_send_connection_notification (jack_engine_t *engine, jack_client_id_t client_id,
  1688. jack_port_id_t self_id, jack_port_id_t other_id, int connected)
  1689. {
  1690. jack_client_internal_t *client;
  1691. jack_event_t event;
  1692. if ((client = jack_client_internal_by_id (engine, client_id)) == 0) {
  1693. jack_error ("no such client %d during connection notification", client_id);
  1694. return -1;
  1695. }
  1696. event.type = (connected ? PortConnected : PortDisconnected);
  1697. event.x.self_id = self_id;
  1698. event.y.other_id = other_id;
  1699. if (jack_deliver_event (engine, client, &event)) {
  1700. jack_error ("cannot send port connection notification to client %s (%s)",
  1701. client->control->name, strerror (errno));
  1702. return -1;
  1703. }
  1704. return 0;
  1705. }
  1706. static void
  1707. jack_audio_port_mixdown (jack_port_t *port, nframes_t nframes)
  1708. {
  1709. GSList *node;
  1710. jack_port_t *input;
  1711. nframes_t n;
  1712. sample_t *buffer;
  1713. sample_t *dst, *src;
  1714. /* by the time we've called this, we've already established
  1715. the existence of more than 1 connection to this input port.
  1716. */
  1717. node = port->connections;
  1718. input = (jack_port_t *) node->data;
  1719. buffer = jack_port_buffer (port);
  1720. memcpy (buffer, jack_port_buffer (input), sizeof (sample_t) * nframes);
  1721. for (node = g_slist_next (node); node; node = g_slist_next (node)) {
  1722. input = (jack_port_t *) node->data;
  1723. n = nframes;
  1724. dst = buffer;
  1725. src = jack_port_buffer (input);
  1726. while (n--) {
  1727. *dst++ += *src++;
  1728. }
  1729. }
  1730. }