|  | @@ -441,7 +441,7 @@ jack_process (jack_engine_t *engine, nframes_t nframes) | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | client = (jack_client_internal_t *) node->data; |  |  | client = (jack_client_internal_t *) node->data; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (!client->control->active) { |  |  |  | 
														
													
														
															
																|  |  |  |  |  | if (!client->control->active || client->control->dead) { | 
														
													
														
															
																|  |  | node = g_slist_next (node); |  |  | node = g_slist_next (node); | 
														
													
														
															
																|  |  | continue; |  |  | continue; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
												
													
														
															
																|  | @@ -470,6 +470,8 @@ jack_process (jack_engine_t *engine, nframes_t nframes) | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | ctl->state = Triggered; // a race exists if we do this after the write(2) |  |  | ctl->state = Triggered; // a race exists if we do this after the write(2) | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | printf ("start subgraph\n"); | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | if (write (client->subgraph_start_fd, &c, sizeof (c)) != sizeof (c)) { |  |  | if (write (client->subgraph_start_fd, &c, sizeof (c)) != sizeof (c)) { | 
														
													
														
															
																|  |  | jack_error ("cannot initiate graph processing (%s)", strerror (errno)); |  |  | jack_error ("cannot initiate graph processing (%s)", strerror (errno)); | 
														
													
														
															
																|  |  | engine->process_errors++; |  |  | engine->process_errors++; | 
														
													
												
													
														
															
																|  | @@ -491,7 +493,7 @@ jack_process (jack_engine_t *engine, nframes_t nframes) | 
														
													
														
															
																|  |  | engine->process_errors++; |  |  | engine->process_errors++; | 
														
													
														
															
																|  |  | break; |  |  | break; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | if (pollfd[0].revents == 0) { |  |  | if (pollfd[0].revents == 0) { | 
														
													
														
															
																|  |  | jack_error ("subgraph starting at %s timed out (state = %d)", client->control->name, client->control->state); |  |  | jack_error ("subgraph starting at %s timed out (state = %d)", client->control->name, client->control->state); | 
														
													
														
															
																|  |  | engine->process_errors++; |  |  | engine->process_errors++; | 
														
													
												
													
														
															
																|  | @@ -508,6 +510,8 @@ jack_process (jack_engine_t *engine, nframes_t nframes) | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | printf ("subgraph done\n"); | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | /* Move to next in-process client (or end of client list) */ |  |  | /* Move to next in-process client (or end of client list) */ | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | while (node) { |  |  | while (node) { | 
														
													
												
													
														
															
																|  | @@ -520,7 +524,7 @@ jack_process (jack_engine_t *engine, nframes_t nframes) | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | return 0; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | return engine->process_errors > 0; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | int |  |  | int | 
														
													
												
													
														
															
																|  | @@ -616,7 +620,9 @@ handle_new_client (jack_engine_t *engine, int client_fd) | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (engine->verbose) { |  |  | if (engine->verbose) { | 
														
													
														
															
																|  |  | fprintf (stderr, "new client: %s, type %d @ %p\n", client->control->name, req.type, client->control); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | fprintf (stderr, "new client: %s, id = %d type %d @ %p fd = %d\n", | 
														
													
														
															
																|  |  |  |  |  | client->control->name, client->control->id, | 
														
													
														
															
																|  |  |  |  |  | req.type, client->control, client_fd); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | res.client_key = client->shm_key; |  |  | res.client_key = client->shm_key; | 
														
													
												
													
														
															
																|  | @@ -648,8 +654,8 @@ handle_new_client (jack_engine_t *engine, int client_fd) | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | pthread_mutex_lock (&engine->graph_lock); |  |  | pthread_mutex_lock (&engine->graph_lock); | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | engine->clients = g_slist_prepend (engine->clients, client); |  |  | engine->clients = g_slist_prepend (engine->clients, client); | 
														
													
														
															
																|  |  | pthread_mutex_unlock (&engine->graph_lock); |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (client->control->type != ClientDynamic) { |  |  | if (client->control->type != ClientDynamic) { | 
														
													
														
															
																|  |  | if (engine->pfd_max >= engine->pfd_size) { |  |  | if (engine->pfd_max >= engine->pfd_size) { | 
														
													
												
													
														
															
																|  | @@ -662,6 +668,7 @@ handle_new_client (jack_engine_t *engine, int client_fd) | 
														
													
														
															
																|  |  | engine->pfd_max++; |  |  | engine->pfd_max++; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | pthread_mutex_unlock (&engine->graph_lock); | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | return 0; |  |  | return 0; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
												
													
														
															
																|  | @@ -678,6 +685,8 @@ handle_client_ack_connection (jack_engine_t *engine, int client_fd) | 
														
													
														
															
																|  |  | jack_error ("cannot read ACK connection request from client"); |  |  | jack_error ("cannot read ACK connection request from client"); | 
														
													
														
															
																|  |  | return -1; |  |  | return -1; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | printf ("ack message, id = %lu\n", req.client_id); | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | if ((client = jack_client_internal_by_id (engine, req.client_id)) == NULL) { |  |  | if ((client = jack_client_internal_by_id (engine, req.client_id)) == NULL) { | 
														
													
														
															
																|  |  | jack_error ("unknown client ID in ACK connection request"); |  |  | jack_error ("unknown client ID in ACK connection request"); | 
														
													
												
													
														
															
																|  | @@ -696,21 +705,6 @@ handle_client_ack_connection (jack_engine_t *engine, int client_fd) | 
														
													
														
															
																|  |  | return 0; |  |  | return 0; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | static int |  |  |  | 
														
													
														
															
																|  |  | jack_client_drop (jack_engine_t *engine, jack_client_id_t id) |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | { |  |  |  | 
														
													
														
															
																|  |  | jack_client_internal_t *client; |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | if ((client = jack_client_internal_by_id (engine, id)) == 0) { |  |  |  | 
														
													
														
															
																|  |  | jack_error ("unknown client ID in DropClient request"); |  |  |  | 
														
													
														
															
																|  |  | return -1; |  |  |  | 
														
													
														
															
																|  |  | } |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | jack_remove_client (engine, client); |  |  |  | 
														
													
														
															
																|  |  | return 0; |  |  |  | 
														
													
														
															
																|  |  | } |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | static int |  |  | static int | 
														
													
														
															
																|  |  | jack_client_activate (jack_engine_t *engine, jack_client_id_t id) |  |  | jack_client_activate (jack_engine_t *engine, jack_client_id_t id) | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | @@ -758,7 +752,7 @@ jack_client_do_deactivate (jack_engine_t *engine, jack_client_internal_t *client | 
														
													
														
															
																|  |  | if (!jack_client_is_inprocess (client)) { |  |  | if (!jack_client_is_inprocess (client)) { | 
														
													
														
															
																|  |  | engine->external_client_cnt--; |  |  | engine->external_client_cnt--; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | jack_sort_graph (engine, FALSE); |  |  | jack_sort_graph (engine, FALSE); | 
														
													
														
															
																|  |  | return 0; |  |  | return 0; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
												
													
														
															
																|  | @@ -839,7 +833,6 @@ jack_set_timebase (jack_engine_t *engine, jack_client_id_t client) | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | static int |  |  | static int | 
														
													
														
															
																|  |  | handle_client_jack_error (jack_engine_t *engine, int fd) |  |  | handle_client_jack_error (jack_engine_t *engine, int fd) | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | { |  |  | { | 
														
													
														
															
																|  |  | jack_client_internal_t *client = 0; |  |  | jack_client_internal_t *client = 0; | 
														
													
														
															
																|  |  | GSList *node; |  |  | GSList *node; | 
														
													
												
													
														
															
																|  | @@ -854,8 +847,8 @@ handle_client_jack_error (jack_engine_t *engine, int fd) | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (client == 0) { |  |  | if (client == 0) { | 
														
													
														
															
																|  |  |  |  |  | jack_error ("no client found for fd %d\n", fd); | 
														
													
														
															
																|  |  | pthread_mutex_unlock (&engine->graph_lock); |  |  | pthread_mutex_unlock (&engine->graph_lock); | 
														
													
														
															
																|  |  | jack_error ("i/o error on unknown client fd %d", fd); |  |  |  | 
														
													
														
															
																|  |  | return -1; |  |  | return -1; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | @@ -891,6 +884,7 @@ handle_client_io (jack_engine_t *engine, int fd) | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (read (client->request_fd, &req, sizeof (req)) < sizeof (req)) { |  |  | if (read (client->request_fd, &req, sizeof (req)) < sizeof (req)) { | 
														
													
														
															
																|  |  | jack_error ("cannot read request from client"); |  |  | jack_error ("cannot read request from client"); | 
														
													
														
															
																|  |  |  |  |  | /* XXX interlock problems with the driver thread here */ | 
														
													
														
															
																|  |  | jack_remove_client (engine, client); |  |  | jack_remove_client (engine, client); | 
														
													
														
															
																|  |  | return -1; |  |  | return -1; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
												
													
														
															
																|  | @@ -918,11 +912,6 @@ handle_client_io (jack_engine_t *engine, int fd) | 
														
													
														
															
																|  |  | req.status = jack_port_do_disconnect (engine, req.x.connect.source_port, req.x.connect.destination_port); |  |  | req.status = jack_port_do_disconnect (engine, req.x.connect.source_port, req.x.connect.destination_port); | 
														
													
														
															
																|  |  | break; |  |  | break; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | case DropClient: |  |  |  | 
														
													
														
															
																|  |  | req.status = jack_client_drop (engine, req.x.client_id); |  |  |  | 
														
													
														
															
																|  |  | reply_fd = -1; |  |  |  | 
														
													
														
															
																|  |  | break; |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | case ActivateClient: |  |  | case ActivateClient: | 
														
													
														
															
																|  |  | req.status = jack_client_activate (engine, req.x.client_id); |  |  | req.status = jack_client_activate (engine, req.x.client_id); | 
														
													
														
															
																|  |  | break; |  |  | break; | 
														
													
												
													
														
															
																|  | @@ -1045,6 +1034,7 @@ jack_server_thread (void *arg) | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (pfd[i].revents & ~POLLIN) { |  |  | if (pfd[i].revents & ~POLLIN) { | 
														
													
														
															
																|  |  |  |  |  | printf ("bad poll status on pfd[%d] (%d) = 0x%x\n", i, pfd[i].fd, pfd[i].revents); | 
														
													
														
															
																|  |  | handle_client_jack_error (engine, pfd[i].fd); |  |  | handle_client_jack_error (engine, pfd[i].fd); | 
														
													
														
															
																|  |  | } else if (pfd[i].revents & POLLIN) { |  |  | } else if (pfd[i].revents & POLLIN) { | 
														
													
														
															
																|  |  | if (handle_client_io (engine, pfd[i].fd)) { |  |  | if (handle_client_io (engine, pfd[i].fd)) { | 
														
													
												
													
														
															
																|  | @@ -1196,19 +1186,8 @@ jack_become_real_time (pthread_t thread, int priority) | 
														
													
														
															
																|  |  | return 0; |  |  | return 0; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | void |  |  |  | 
														
													
														
															
																|  |  | cancel_cleanup1 (void *arg) |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | { |  |  |  | 
														
													
														
															
																|  |  | jack_engine_t *engine = (jack_engine_t *) arg; |  |  |  | 
														
													
														
															
																|  |  | if (engine->verbose) { |  |  |  | 
														
													
														
															
																|  |  | fprintf (stderr, "audio thread cancelled or finished\n"); |  |  |  | 
														
													
														
															
																|  |  | } |  |  |  | 
														
													
														
															
																|  |  | engine->driver->stop (engine->driver); |  |  |  | 
														
													
														
															
																|  |  | } |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | void |  |  |  | 
														
													
														
															
																|  |  | cancel_cleanup2 (int status, void *arg) |  |  |  | 
														
													
														
															
																|  |  |  |  |  | static void | 
														
													
														
															
																|  |  |  |  |  | cancel_cleanup (int status, void *arg) | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | { |  |  | { | 
														
													
														
															
																|  |  | jack_engine_t *engine = (jack_engine_t *) arg; |  |  | jack_engine_t *engine = (jack_engine_t *) arg; | 
														
													
												
													
														
															
																|  | @@ -1230,7 +1209,7 @@ jack_main_thread (void *arg) | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); |  |  | pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); | 
														
													
														
															
																|  |  | on_exit (cancel_cleanup2, engine); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | on_exit (cancel_cleanup, engine); | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (driver->start (driver)) { |  |  | if (driver->start (driver)) { | 
														
													
														
															
																|  |  | jack_error ("cannot start driver"); |  |  | jack_error ("cannot start driver"); | 
														
													
												
													
														
															
																|  | @@ -1238,7 +1217,20 @@ jack_main_thread (void *arg) | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | while (1) { |  |  | while (1) { | 
														
													
														
															
																|  |  | if (driver->wait (driver)) { |  |  |  | 
														
													
														
															
																|  |  |  |  |  | switch (driver->wait (driver)) { | 
														
													
														
															
																|  |  |  |  |  | case -1: | 
														
													
														
															
																|  |  |  |  |  | jack_error ("driver wait function failed, exiting"); | 
														
													
														
															
																|  |  |  |  |  | pthread_exit (0); | 
														
													
														
															
																|  |  |  |  |  | break; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | case  1: | 
														
													
														
															
																|  |  |  |  |  | if (driver->start (driver)) { | 
														
													
														
															
																|  |  |  |  |  | jack_error ("cannot restart driver"); | 
														
													
														
															
																|  |  |  |  |  | pthread_exit (0); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | break; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | default: | 
														
													
														
															
																|  |  | break; |  |  | break; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
												
													
														
															
																|  | @@ -1396,11 +1388,17 @@ jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client) | 
														
													
														
															
																|  |  | GSList *node; |  |  | GSList *node; | 
														
													
														
															
																|  |  | int i; |  |  | int i; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (engine->verbose) { |  |  |  | 
														
													
														
															
																|  |  | fprintf (stderr, "removing client %s\n", client->control->name); |  |  |  | 
														
													
														
															
																|  |  | } |  |  |  | 
														
													
														
															
																|  |  |  |  |  | /* caller must hold the graph_lock */ | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | printf ("remove client\n"); | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | /* these stop the process() loop from paying this client any attention, | 
														
													
														
															
																|  |  |  |  |  | as well as stopping jack_deliver_event() from bothering to try to | 
														
													
														
															
																|  |  |  |  |  | talk to the client. | 
														
													
														
															
																|  |  |  |  |  | */ | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | client->control->dead = TRUE; |  |  | client->control->dead = TRUE; | 
														
													
														
															
																|  |  |  |  |  | client->control->active = FALSE; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (client == engine->timebase_client) { |  |  | if (client == engine->timebase_client) { | 
														
													
														
															
																|  |  | engine->timebase_client = 0; |  |  | engine->timebase_client = 0; | 
														
													
												
													
														
															
																|  | @@ -1409,6 +1407,11 @@ jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client) | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | jack_client_disconnect (engine, client); |  |  | jack_client_disconnect (engine, client); | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | /* try to force the server thread to return from poll */ | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | close (client->event_fd); | 
														
													
														
															
																|  |  |  |  |  | close (client->request_fd); | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | for (node = engine->clients; node; node = g_slist_next (node)) { |  |  | for (node = engine->clients; node; node = g_slist_next (node)) { | 
														
													
														
															
																|  |  | if (((jack_client_internal_t *) node->data)->control->id == client->control->id) { |  |  | if (((jack_client_internal_t *) node->data)->control->id == client->control->id) { | 
														
													
														
															
																|  |  | engine->clients = g_slist_remove_link (engine->clients, node); |  |  | engine->clients = g_slist_remove_link (engine->clients, node); | 
														
													
												
													
														
															
																|  | @@ -1416,13 +1419,13 @@ jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client) | 
														
													
														
															
																|  |  | break; |  |  | break; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | jack_client_do_deactivate (engine, client); |  |  | jack_client_do_deactivate (engine, client); | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | /* rearrange the pollfd array so that things work right the |  |  | /* rearrange the pollfd array so that things work right the | 
														
													
														
															
																|  |  | next time we go into poll(2). |  |  | next time we go into poll(2). | 
														
													
														
															
																|  |  | */ |  |  | */ | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | for (i = 0; i < engine->pfd_max; i++) { |  |  | for (i = 0; i < engine->pfd_max; i++) { | 
														
													
														
															
																|  |  | if (engine->pfd[i].fd == client->request_fd) { |  |  | if (engine->pfd[i].fd == client->request_fd) { | 
														
													
														
															
																|  |  | if (i+1 < engine->pfd_max) { |  |  | if (i+1 < engine->pfd_max) { | 
														
													
												
													
														
															
																|  | @@ -1432,9 +1435,6 @@ jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client) | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | close (client->event_fd); |  |  |  | 
														
													
														
															
																|  |  | close (client->request_fd); |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | jack_client_delete (engine, client); |  |  | jack_client_delete (engine, client); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | @@ -1497,7 +1497,8 @@ static int | 
														
													
														
															
																|  |  | jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, jack_event_t *event) |  |  | jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, jack_event_t *event) | 
														
													
														
															
																|  |  | { |  |  | { | 
														
													
														
															
																|  |  | char status; |  |  | char status; | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  |  |  |  | int client_err = 0; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | if (client->control->dead) { |  |  | if (client->control->dead) { | 
														
													
														
															
																|  |  | return 0; |  |  | return 0; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
												
													
														
															
																|  | @@ -1530,12 +1531,18 @@ jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, jack_ | 
														
													
														
															
																|  |  | } else { |  |  | } else { | 
														
													
														
															
																|  |  | if (write (client->event_fd, event, sizeof (*event)) != sizeof (*event)) { |  |  | if (write (client->event_fd, event, sizeof (*event)) != sizeof (*event)) { | 
														
													
														
															
																|  |  | jack_error ("cannot send event to client [%s] (%s)", client->control->name, strerror (errno)); |  |  | jack_error ("cannot send event to client [%s] (%s)", client->control->name, strerror (errno)); | 
														
													
														
															
																|  |  | return -1; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | client_err++; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | if (read (client->event_fd, &status, sizeof (status)) != sizeof (status)) { |  |  |  | 
														
													
														
															
																|  |  |  |  |  | if (!client_err && (read (client->event_fd, &status, sizeof (status)) != sizeof (status))) { | 
														
													
														
															
																|  |  | jack_error ("cannot read event response from client [%s] (%s)", client->control->name, strerror (errno)); |  |  | jack_error ("cannot read event response from client [%s] (%s)", client->control->name, strerror (errno)); | 
														
													
														
															
																|  |  | return -1; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | client_err++; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | if (client_err || status != 0) { | 
														
													
														
															
																|  |  |  |  |  | pthread_mutex_lock (&engine->graph_lock); | 
														
													
														
															
																|  |  |  |  |  | jack_remove_client (engine, client); | 
														
													
														
															
																|  |  |  |  |  | pthread_mutex_unlock (&engine->graph_lock); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | @@ -1704,20 +1711,37 @@ static int | 
														
													
														
															
																|  |  | jack_client_sort (jack_client_internal_t *a, jack_client_internal_t *b) |  |  | jack_client_sort (jack_client_internal_t *a, jack_client_internal_t *b) | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | { |  |  | { | 
														
													
														
															
																|  |  | /* the driver client always comes after everything else */ |  |  |  | 
														
													
														
															
																|  |  |  |  |  | if (g_slist_find (a->fed_by, b)) { | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  |  |  |  | if (g_slist_find (b->fed_by, a)) { | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (a->control->type == ClientDriver) { |  |  |  | 
														
													
														
															
																|  |  | return 1; |  |  |  | 
														
													
														
															
																|  |  | } |  |  |  | 
														
													
														
															
																|  |  |  |  |  | /* feedback loop: if `a' is the driver | 
														
													
														
															
																|  |  |  |  |  | client, let that execute first. | 
														
													
														
															
																|  |  |  |  |  | */ | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (b->control->type == ClientDriver) { |  |  |  | 
														
													
														
															
																|  |  | return -1; |  |  |  | 
														
													
														
															
																|  |  | } |  |  |  | 
														
													
														
															
																|  |  |  |  |  | if (a->control->type == ClientDriver) { | 
														
													
														
															
																|  |  |  |  |  | /* b comes after a */ | 
														
													
														
															
																|  |  |  |  |  | return -1; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (g_slist_find (a->fed_by, b)) { |  |  |  | 
														
													
														
															
																|  |  | /* a comes after b */ |  |  | /* a comes after b */ | 
														
													
														
															
																|  |  | return 1; |  |  | return 1; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | } else if (g_slist_find (b->fed_by, a)) { |  |  | } else if (g_slist_find (b->fed_by, a)) { | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  |  |  |  | if (g_slist_find (a->fed_by, b)) { | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | /* feedback loop: if `b' is the driver | 
														
													
														
															
																|  |  |  |  |  | client, let that execute first. | 
														
													
														
															
																|  |  |  |  |  | */ | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | if (b->control->type == ClientDriver) { | 
														
													
														
															
																|  |  |  |  |  | /* b comes before a */ | 
														
													
														
															
																|  |  |  |  |  | return 1; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | /* b comes after a */ |  |  | /* b comes after a */ | 
														
													
														
															
																|  |  | return -1; |  |  | return -1; | 
														
													
														
															
																|  |  | } else { |  |  | } else { | 
														
													
												
													
														
															
																|  | @@ -1775,7 +1799,9 @@ jack_client_feeds (jack_client_internal_t *might, jack_client_internal_t *target | 
														
													
														
															
																|  |  | * |  |  | * | 
														
													
														
															
																|  |  | * 3) now sort according to whether or not client1->fed_by (client2) is true. |  |  | * 3) now sort according to whether or not client1->fed_by (client2) is true. | 
														
													
														
															
																|  |  | *    if the condition is true, client2 must execute before client1 |  |  | *    if the condition is true, client2 must execute before client1 | 
														
													
														
															
																|  |  |  |  |  | * | 
														
													
														
															
																|  |  | */ |  |  | */ | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | static void |  |  | static void | 
														
													
														
															
																|  |  | jack_sort_graph (jack_engine_t *engine, int take_lock) |  |  | jack_sort_graph (jack_engine_t *engine, int take_lock) | 
														
													
														
															
																|  |  | { |  |  | { | 
														
													
												
													
														
															
																|  | @@ -2197,10 +2223,14 @@ static void | 
														
													
														
															
																|  |  | jack_port_release (jack_engine_t *engine, jack_port_internal_t *port) |  |  | jack_port_release (jack_engine_t *engine, jack_port_internal_t *port) | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | { |  |  | { | 
														
													
														
															
																|  |  | /* XXX add the buffer used by the port back the (correct) freelist */ |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | pthread_mutex_lock (&engine->port_lock); |  |  | pthread_mutex_lock (&engine->port_lock); | 
														
													
														
															
																|  |  | port->shared->in_use = 0; |  |  | port->shared->in_use = 0; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | if (port->buffer_info) { | 
														
													
														
															
																|  |  |  |  |  | pthread_mutex_lock (&engine->buffer_lock); | 
														
													
														
															
																|  |  |  |  |  | engine->port_buffer_freelist = g_slist_prepend (engine->port_buffer_freelist, port->buffer_info); | 
														
													
														
															
																|  |  |  |  |  | pthread_mutex_unlock (&engine->buffer_lock); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  | pthread_mutex_unlock (&engine->port_lock); |  |  | pthread_mutex_unlock (&engine->port_lock); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | @@ -2274,7 +2304,7 @@ jack_port_do_register (jack_engine_t *engine, jack_request_t *req) | 
														
													
														
															
																|  |  | pthread_mutex_unlock (&engine->graph_lock); |  |  | pthread_mutex_unlock (&engine->graph_lock); | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | if (engine->verbose) { |  |  | if (engine->verbose) { | 
														
													
														
															
																|  |  | fprintf (stderr, "registered port %s\n", shared->name); |  |  |  | 
														
													
														
															
																|  |  |  |  |  | fprintf (stderr, "registered port %s, offset = %u\n", shared->name, shared->offset); | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | req->x.port_info.port_id = port_id; |  |  | req->x.port_info.port_id = port_id; | 
														
													
												
													
														
															
																|  | @@ -2349,7 +2379,7 @@ int | 
														
													
														
															
																|  |  | jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port) |  |  | jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port) | 
														
													
														
															
																|  |  | { |  |  | { | 
														
													
														
															
																|  |  | GSList *node; |  |  | GSList *node; | 
														
													
														
															
																|  |  | jack_port_segment_info_t *psi; |  |  |  | 
														
													
														
															
																|  |  |  |  |  | jack_port_segment_info_t *psi = 0; | 
														
													
														
															
																|  |  | jack_port_buffer_info_t *bi; |  |  | jack_port_buffer_info_t *bi; | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | port->shared->shm_key = -1; |  |  | port->shared->shm_key = -1; | 
														
													
												
													
														
															
																|  | @@ -2367,7 +2397,7 @@ jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port) | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | bi = (jack_port_buffer_info_t *) engine->port_buffer_freelist->data; |  |  | bi = (jack_port_buffer_info_t *) engine->port_buffer_freelist->data; | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | for (node = engine->port_segments; node; node = g_slist_next (node)) { |  |  | for (node = engine->port_segments; node; node = g_slist_next (node)) { | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | psi = (jack_port_segment_info_t *) node->data; |  |  | psi = (jack_port_segment_info_t *) node->data; | 
														
													
												
													
														
															
																|  | @@ -2375,9 +2405,9 @@ jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port) | 
														
													
														
															
																|  |  | if (bi->shm_key == psi->shm_key) { |  |  | if (bi->shm_key == psi->shm_key) { | 
														
													
														
															
																|  |  | port->shared->shm_key = psi->shm_key; |  |  | port->shared->shm_key = psi->shm_key; | 
														
													
														
															
																|  |  | port->shared->offset = bi->offset; |  |  | port->shared->offset = bi->offset; | 
														
													
														
															
																|  |  |  |  |  | port->buffer_info = bi; | 
														
													
														
															
																|  |  | break; |  |  | break; | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | } |  |  | } | 
														
													
														
															
																|  |  |  |  |  |  | 
														
													
														
															
																|  |  | if (port->shared->shm_key >= 0) { |  |  | if (port->shared->shm_key >= 0) { | 
														
													
												
													
														
															
																|  | @@ -2417,7 +2447,7 @@ jack_get_port_by_name (jack_engine_t *engine, const char *name) | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | static int |  |  | static int | 
														
													
														
															
																|  |  | jack_send_connection_notification (jack_engine_t *engine, jack_client_id_t client_id, |  |  | jack_send_connection_notification (jack_engine_t *engine, jack_client_id_t client_id, | 
														
													
														
															
																|  |  | jack_port_id_t self_id, jack_port_id_t other_id, int connected) |  |  |  | 
														
													
														
															
																|  |  |  |  |  | jack_port_id_t self_id, jack_port_id_t other_id, int connected) | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | { |  |  | { | 
														
													
														
															
																|  |  | jack_client_internal_t *client; |  |  | jack_client_internal_t *client; | 
														
													
												
													
														
															
																|  | 
 |