62 typedef struct xmms_ipc_client_St {
82 static GMutex *ipc_servers_lock;
83 static GList *ipc_servers = NULL;
85 static GMutex *ipc_object_pool_lock;
101 if (argument_list &&
xmmsv_list_get (argument_list, i, &arg_value)) {
109 if (actual_type != expected_type) {
110 XMMS_DBG (
"Expected type %i, but got type %i",
111 expected_type, actual_type);
117 arg->
values[i] = arg_value;
127 xmms_log_error (
"Failed to serialize the return value into the IPC message!");
156 g_mutex_lock (client->lock);
158 g_mutex_unlock (client->lock);
186 g_mutex_lock (client->lock);
187 client->broadcasts[broadcastid] =
188 g_list_append (client->broadcasts[broadcastid],
191 g_mutex_unlock (client->lock);
202 uint32_t objid, cmdid;
205 g_return_if_fail (msg);
212 "Ignoring command.");
219 xmms_ipc_register_signal (client, msg, arguments);
221 xmms_ipc_register_broadcast (client, msg, arguments);
234 g_mutex_lock (ipc_object_pool_lock);
235 object = ipc_object_pool->objects[objid];
236 g_mutex_unlock (ipc_object_pool_lock);
243 cmd = g_tree_lookup (object->
cmds, GUINT_TO_POINTER (cmdid));
253 if (!type_and_msg_to_arg (cmd->
args[i], arguments, &arg, i)) {
259 "Maybe the client or libxmmsclient "
260 "needs to be updated.");
277 xmms_ipc_handle_cmd_value (retmsg, arg.
retval);
304 g_mutex_lock (client->lock);
305 xmms_ipc_client_msg_write (client, retmsg);
306 g_mutex_unlock (client->lock);
316 xmms_ipc_client_read_cb (GIOChannel *iochan,
321 bool disconnect = FALSE;
323 g_return_val_if_fail (client, FALSE);
325 if (cond & G_IO_IN) {
327 if (!client->read_msg) {
333 client->read_msg = NULL;
334 process_msg (client, msg);
342 if (disconnect || (cond & G_IO_HUP)) {
343 if (client->read_msg) {
345 client->read_msg = NULL;
348 g_main_loop_quit (client->ml);
352 if (cond & G_IO_ERR) {
354 g_main_loop_quit (client->ml);
362 xmms_ipc_client_write_cb (GIOChannel *iochan,
367 bool disconnect = FALSE;
369 g_return_val_if_fail (client, FALSE);
374 g_mutex_lock (client->lock);
375 msg = g_queue_peek_head (client->out_msg);
376 g_mutex_unlock (client->lock);
392 g_mutex_lock (client->lock);
393 g_queue_pop_head (client->out_msg);
394 g_mutex_unlock (client->lock);
403 xmms_ipc_client_thread (gpointer data)
408 source = g_io_create_watch (client->iochan, G_IO_IN | G_IO_ERR | G_IO_HUP);
409 g_source_set_callback (source,
410 (GSourceFunc) xmms_ipc_client_read_cb,
413 g_source_attach (source, g_main_loop_get_context (client->ml));
414 g_source_unref (source);
416 g_main_loop_run (client->ml);
418 xmms_ipc_client_destroy (client);
427 GMainContext *context;
430 g_return_val_if_fail (transport, NULL);
434 context = g_main_context_new ();
435 client->ml = g_main_loop_new (context, FALSE);
436 g_main_context_unref (context);
439 client->iochan = g_io_channel_unix_new (fd);
440 g_return_val_if_fail (client->iochan, NULL);
445 g_io_channel_set_encoding (client->iochan, NULL, NULL);
446 g_io_channel_set_buffered (client->iochan, FALSE);
448 client->transport = transport;
450 client->out_msg = g_queue_new ();
451 client->lock = g_mutex_new ();
464 g_mutex_lock (client->ipc->mutex_lock);
465 client->ipc->clients = g_list_remove (client->ipc->clients, client);
466 g_mutex_unlock (client->ipc->mutex_lock);
469 g_main_loop_unref (client->ml);
470 g_io_channel_unref (client->iochan);
474 g_mutex_lock (client->lock);
475 while (!g_queue_is_empty (client->out_msg)) {
480 g_queue_free (client->out_msg);
483 g_list_free (client->broadcasts[i]);
486 g_mutex_unlock (client->lock);
487 g_mutex_free (client->lock);
499 XMMS_DBG (
"Shutting down ipc server threads through config property \"core.ipcsocket\" change.");
513 gboolean queue_empty;
515 g_return_val_if_fail (client, FALSE);
516 g_return_val_if_fail (msg, FALSE);
518 queue_empty = g_queue_is_empty (client->out_msg);
519 g_queue_push_tail (client->out_msg, msg);
523 GMainContext *context = g_main_loop_get_context (client->ml);
524 GSource *source = g_io_create_watch (client->iochan, G_IO_OUT);
526 g_source_set_callback (source,
527 (GSourceFunc) xmms_ipc_client_write_cb,
530 g_source_attach (source, context);
531 g_source_unref (source);
533 g_main_context_wakeup (context);
540 xmms_ipc_source_accept (GIOChannel *chan, GIOCondition cond, gpointer data)
546 if (!(cond & G_IO_IN)) {
558 client = xmms_ipc_client_new (ipc, transport);
564 g_mutex_lock (ipc->mutex_lock);
565 ipc->clients = g_list_append (ipc->clients, client);
566 g_mutex_unlock (ipc->mutex_lock);
571 g_thread_create (xmms_ipc_client_thread, client, FALSE, NULL);
580 xmms_ipc_setup_server_internaly (
xmms_ipc_t *ipc)
582 g_mutex_lock (ipc->mutex_lock);
585 g_io_channel_set_close_on_unref (ipc->chan, TRUE);
586 g_io_channel_set_encoding (ipc->chan, NULL, NULL);
587 g_io_channel_set_buffered (ipc->chan, FALSE);
589 g_io_add_watch (ipc->chan, G_IO_IN | G_IO_HUP | G_IO_ERR,
590 xmms_ipc_source_accept, ipc);
591 g_mutex_unlock (ipc->mutex_lock);
604 g_mutex_lock (ipc_servers_lock);
606 for (s = ipc_servers; s; s = g_list_next (s)) {
608 g_mutex_lock (ipc->mutex_lock);
609 for (c = ipc->clients; c; c = g_list_next (c)) {
611 g_mutex_lock (cli->lock);
612 if (cli->pendingsignals[signalid]) {
613 g_mutex_unlock (cli->lock);
614 g_mutex_unlock (ipc->mutex_lock);
615 g_mutex_unlock (ipc_servers_lock);
618 g_mutex_unlock (cli->lock);
620 g_mutex_unlock (ipc->mutex_lock);
623 g_mutex_unlock (ipc_servers_lock);
631 guint signalid = GPOINTER_TO_UINT (userdata);
635 g_mutex_lock (ipc_servers_lock);
637 for (s = ipc_servers; s && s->data; s = g_list_next (s)) {
639 g_mutex_lock (ipc->mutex_lock);
640 for (c = ipc->clients; c; c = g_list_next (c)) {
642 g_mutex_lock (cli->lock);
643 if (cli->pendingsignals[signalid]) {
646 xmms_ipc_handle_cmd_value (msg, arg);
647 xmms_ipc_client_msg_write (cli, msg);
648 cli->pendingsignals[signalid] = 0;
650 g_mutex_unlock (cli->lock);
652 g_mutex_unlock (ipc->mutex_lock);
655 g_mutex_unlock (ipc_servers_lock);
663 guint broadcastid = GPOINTER_TO_UINT (userdata);
668 g_mutex_lock (ipc_servers_lock);
670 for (s = ipc_servers; s && s->data; s = g_list_next (s)) {
672 g_mutex_lock (ipc->mutex_lock);
673 for (c = ipc->clients; c; c = g_list_next (c)) {
676 g_mutex_lock (cli->lock);
677 for (l = cli->broadcasts[broadcastid]; l; l = g_list_next (l)) {
680 xmms_ipc_handle_cmd_value (msg, arg);
681 xmms_ipc_client_msg_write (cli, msg);
683 g_mutex_unlock (cli->lock);
685 g_mutex_unlock (ipc->mutex_lock);
687 g_mutex_unlock (ipc_servers_lock);
696 g_return_if_fail (
object);
697 g_mutex_lock (ipc_object_pool_lock);
699 ipc_object_pool->broadcasts[signalid] = object;
700 xmms_object_connect (
object, signalid, xmms_ipc_broadcast_cb, GUINT_TO_POINTER (signalid));
702 g_mutex_unlock (ipc_object_pool_lock);
713 g_mutex_lock (ipc_object_pool_lock);
714 obj = ipc_object_pool->broadcasts[signalid];
717 ipc_object_pool->broadcasts[signalid] = NULL;
719 g_mutex_unlock (ipc_object_pool_lock);
728 g_return_if_fail (
object);
730 g_mutex_lock (ipc_object_pool_lock);
731 ipc_object_pool->signals[signalid] = object;
733 g_mutex_unlock (ipc_object_pool_lock);
744 g_mutex_lock (ipc_object_pool_lock);
745 obj = ipc_object_pool->signals[signalid];
748 ipc_object_pool->signals[signalid] = NULL;
750 g_mutex_unlock (ipc_object_pool_lock);
760 g_mutex_lock (ipc_object_pool_lock);
761 ipc_object_pool->objects[objectid] = object;
762 g_mutex_unlock (ipc_object_pool_lock);
771 g_mutex_lock (ipc_object_pool_lock);
772 ipc_object_pool->objects[objectid] = NULL;
773 g_mutex_unlock (ipc_object_pool_lock);
782 ipc_servers_lock = g_mutex_new ();
783 ipc_object_pool_lock = g_mutex_new ();
798 g_mutex_lock (ipc->mutex_lock);
799 g_source_remove_by_user_data (ipc);
800 g_io_channel_unref (ipc->chan);
803 for (c = ipc->clients; c; c = g_list_next (c)) {
809 g_list_free (ipc->clients);
810 g_mutex_unlock (ipc->mutex_lock);
811 g_mutex_free (ipc->mutex_lock);
824 GList *s = ipc_servers;
827 g_mutex_lock (ipc_servers_lock);
831 ipc_servers = g_list_remove (ipc_servers, ipc);
832 xmms_ipc_shutdown_server (ipc);
834 g_mutex_unlock (ipc_servers_lock);
847 gint i = 0, num_init = 0;
848 g_return_val_if_fail (path, FALSE);
850 split = g_strsplit (path,
";", 0);
852 for (i = 0; split && split[i]; i++) {
855 XMMS_DBG (
"No IPC server initialized.");
862 xmms_log_error (
"Couldn't setup IPC listening on '%s'.", split[i]);
867 ipc->mutex_lock = g_mutex_new ();
868 ipc->transport = transport;
869 ipc->signals = ipc_object_pool->signals;
870 ipc->broadcasts = ipc_object_pool->broadcasts;
871 ipc->objects = ipc_object_pool->objects;
873 xmms_ipc_setup_server_internaly (ipc);
876 g_mutex_lock (ipc_servers_lock);
877 ipc_servers = g_list_prepend (ipc_servers, ipc);
878 g_mutex_unlock (ipc_servers_lock);