00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <glib.h>
00018 #include <string.h>
00019
00020 #include "xmms/xmms_log.h"
00021 #include "xmms/xmms_config.h"
00022 #include "xmmspriv/xmms_ipc.h"
00023 #include "xmmsc/xmmsc_ipc_msg.h"
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 typedef struct xmms_ipc_object_pool_t {
00039 xmms_object_t *objects[XMMS_IPC_OBJECT_END];
00040 xmms_object_t *signals[XMMS_IPC_SIGNAL_END];
00041 xmms_object_t *broadcasts[XMMS_IPC_SIGNAL_END];
00042 } xmms_ipc_object_pool_t;
00043
00044
00045
00046
00047
00048 struct xmms_ipc_St {
00049 xmms_ipc_transport_t *transport;
00050 GList *clients;
00051 GIOChannel *chan;
00052 GMutex *mutex_lock;
00053 xmms_object_t **objects;
00054 xmms_object_t **signals;
00055 xmms_object_t **broadcasts;
00056 };
00057
00058
00059
00060
00061
00062 typedef struct xmms_ipc_client_St {
00063 GMainLoop *ml;
00064 GIOChannel *iochan;
00065
00066 xmms_ipc_transport_t *transport;
00067 xmms_ipc_msg_t *read_msg;
00068 xmms_ipc_t *ipc;
00069
00070
00071
00072
00073 GMutex *lock;
00074
00075
00076 GQueue *out_msg;
00077
00078 guint pendingsignals[XMMS_IPC_SIGNAL_END];
00079 GList *broadcasts[XMMS_IPC_SIGNAL_END];
00080 } xmms_ipc_client_t;
00081
00082 static GMutex *ipc_servers_lock;
00083 static GList *ipc_servers = NULL;
00084
00085 static GMutex *ipc_object_pool_lock;
00086 static struct xmms_ipc_object_pool_t *ipc_object_pool = NULL;
00087
00088 static void xmms_ipc_client_destroy (xmms_ipc_client_t *client);
00089
00090 static gboolean xmms_ipc_client_msg_write (xmms_ipc_client_t *client, xmms_ipc_msg_t *msg);
00091
00092
00093 static gboolean
00094 type_and_msg_to_arg (xmmsv_type_t type, xmms_ipc_msg_t *msg, xmms_object_cmd_arg_t *arg, gint i)
00095 {
00096 if (!xmms_ipc_msg_get_value_of_type_alloc (msg, type, &arg->values[i])) {
00097 XMMS_DBG ("Failed fetching the value of the argument from the IPC message!");
00098 return FALSE;
00099 }
00100
00101 return TRUE;
00102 }
00103
00104 static void
00105 xmms_ipc_handle_cmd_value (xmms_ipc_msg_t *msg, xmmsv_t *val)
00106 {
00107 if (xmms_ipc_msg_put_value (msg, val) == (uint32_t) -1) {
00108 xmms_log_error ("Failed to serialize the return value into the IPC message!");
00109 }
00110 }
00111
00112 static void
00113 process_msg (xmms_ipc_client_t *client, xmms_ipc_msg_t *msg)
00114 {
00115 xmms_object_t *object;
00116 xmms_object_cmd_desc_t *cmd = NULL;
00117 xmms_object_cmd_arg_t arg;
00118 xmms_ipc_msg_t *retmsg;
00119 uint32_t objid, cmdid;
00120 gint i;
00121
00122 g_return_if_fail (msg);
00123
00124 objid = xmms_ipc_msg_get_object (msg);
00125 cmdid = xmms_ipc_msg_get_cmd (msg);
00126
00127 if (objid == XMMS_IPC_OBJECT_SIGNAL &&
00128 cmdid == XMMS_IPC_CMD_SIGNAL) {
00129 gint32 signalid;
00130
00131 if (!xmms_ipc_msg_get_int32 (msg, &signalid)) {
00132 xmms_log_error ("No signalid in this msg?!");
00133 return;
00134 }
00135
00136 if (signalid < 0 || signalid >= XMMS_IPC_SIGNAL_END) {
00137 xmms_log_error ("Bad signal id (%d)", signalid);
00138 return;
00139 }
00140
00141 g_mutex_lock (client->lock);
00142 client->pendingsignals[signalid] = xmms_ipc_msg_get_cookie (msg);
00143 g_mutex_unlock (client->lock);
00144 return;
00145 } else if (objid == XMMS_IPC_OBJECT_SIGNAL &&
00146 cmdid == XMMS_IPC_CMD_BROADCAST) {
00147 gint32 broadcastid;
00148
00149 if (!xmms_ipc_msg_get_int32 (msg, &broadcastid)) {
00150 xmms_log_error ("No broadcastid in this msg?!");
00151 return;
00152 }
00153
00154 if (broadcastid < 0 || broadcastid >= XMMS_IPC_SIGNAL_END) {
00155 xmms_log_error ("Bad broadcast id (%d)", broadcastid);
00156 return;
00157 }
00158
00159 g_mutex_lock (client->lock);
00160 client->broadcasts[broadcastid] =
00161 g_list_append (client->broadcasts[broadcastid],
00162 GUINT_TO_POINTER (xmms_ipc_msg_get_cookie (msg)));
00163
00164 g_mutex_unlock (client->lock);
00165 return;
00166 }
00167
00168 if (objid >= XMMS_IPC_OBJECT_END) {
00169 xmms_log_error ("Bad object id (%d)", objid);
00170 return;
00171 }
00172
00173 g_mutex_lock (ipc_object_pool_lock);
00174 object = ipc_object_pool->objects[objid];
00175 g_mutex_unlock (ipc_object_pool_lock);
00176 if (!object) {
00177 xmms_log_error ("Object %d was not found!", objid);
00178 return;
00179 }
00180
00181 if (cmdid >= XMMS_IPC_CMD_END) {
00182 xmms_log_error ("Bad command id (%d)", cmdid);
00183 return;
00184 }
00185
00186 if (object->cmds)
00187 cmd = g_tree_lookup (object->cmds, GUINT_TO_POINTER (cmdid));
00188
00189 if (!cmd) {
00190 xmms_log_error ("No such cmd %d on object %d", cmdid, objid);
00191 return;
00192 }
00193
00194 xmms_object_cmd_arg_init (&arg);
00195
00196 for (i = 0; i < XMMS_OBJECT_CMD_MAX_ARGS; i++) {
00197 if (!type_and_msg_to_arg (cmd->args[i], msg, &arg, i)) {
00198 xmms_log_error ("Error parsing args");
00199 retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR);
00200 xmms_ipc_msg_put_string (retmsg, "Corrupt msg");
00201 goto err;
00202 }
00203
00204 }
00205
00206 xmms_object_cmd_call (object, cmdid, &arg);
00207 if (xmms_error_isok (&arg.error)) {
00208 retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY);
00209 xmms_ipc_handle_cmd_value (retmsg, arg.retval);
00210 } else {
00211
00212
00213
00214 retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR);
00215 xmms_ipc_msg_put_string (retmsg, xmms_error_message_get (&arg.error));
00216
00217
00218
00219
00220 }
00221
00222 if (arg.retval)
00223 xmmsv_unref (arg.retval);
00224
00225 err:
00226 for (i = 0; i < XMMS_OBJECT_CMD_MAX_ARGS; i++) {
00227 xmmsv_unref (arg.values[i]);
00228 }
00229 xmms_ipc_msg_set_cookie (retmsg, xmms_ipc_msg_get_cookie (msg));
00230 g_mutex_lock (client->lock);
00231 xmms_ipc_client_msg_write (client, retmsg);
00232 g_mutex_unlock (client->lock);
00233 }
00234
00235
00236 static gboolean
00237 xmms_ipc_client_read_cb (GIOChannel *iochan,
00238 GIOCondition cond,
00239 gpointer data)
00240 {
00241 xmms_ipc_client_t *client = data;
00242 bool disconnect = FALSE;
00243
00244 g_return_val_if_fail (client, FALSE);
00245
00246 if (cond & G_IO_IN) {
00247 while (TRUE) {
00248 if (!client->read_msg) {
00249 client->read_msg = xmms_ipc_msg_alloc ();
00250 }
00251
00252 if (xmms_ipc_msg_read_transport (client->read_msg, client->transport, &disconnect)) {
00253 xmms_ipc_msg_t *msg = client->read_msg;
00254 client->read_msg = NULL;
00255 process_msg (client, msg);
00256 xmms_ipc_msg_destroy (msg);
00257 } else {
00258 break;
00259 }
00260 }
00261 }
00262
00263 if (disconnect || (cond & G_IO_HUP)) {
00264 if (client->read_msg) {
00265 xmms_ipc_msg_destroy (client->read_msg);
00266 client->read_msg = NULL;
00267 }
00268 XMMS_DBG ("disconnect was true!");
00269 g_main_loop_quit (client->ml);
00270 return FALSE;
00271 }
00272
00273 if (cond & G_IO_ERR) {
00274 xmms_log_error ("Client got error, maybe connection died?");
00275 g_main_loop_quit (client->ml);
00276 return FALSE;
00277 }
00278
00279 return TRUE;
00280 }
00281
00282 static gboolean
00283 xmms_ipc_client_write_cb (GIOChannel *iochan,
00284 GIOCondition cond,
00285 gpointer data)
00286 {
00287 xmms_ipc_client_t *client = data;
00288 bool disconnect = FALSE;
00289
00290 g_return_val_if_fail (client, FALSE);
00291
00292 while (TRUE) {
00293 xmms_ipc_msg_t *msg;
00294
00295 g_mutex_lock (client->lock);
00296 msg = g_queue_peek_head (client->out_msg);
00297 g_mutex_unlock (client->lock);
00298
00299 if (!msg)
00300 break;
00301
00302 if (!xmms_ipc_msg_write_transport (msg,
00303 client->transport,
00304 &disconnect)) {
00305 if (disconnect) {
00306 break;
00307 } else {
00308
00309 return TRUE;
00310 }
00311 }
00312
00313 g_mutex_lock (client->lock);
00314 g_queue_pop_head (client->out_msg);
00315 g_mutex_unlock (client->lock);
00316
00317 xmms_ipc_msg_destroy (msg);
00318 }
00319
00320 return FALSE;
00321 }
00322
00323 static gpointer
00324 xmms_ipc_client_thread (gpointer data)
00325 {
00326 xmms_ipc_client_t *client = data;
00327 GSource *source;
00328
00329 source = g_io_create_watch (client->iochan, G_IO_IN | G_IO_ERR | G_IO_HUP);
00330 g_source_set_callback (source,
00331 (GSourceFunc) xmms_ipc_client_read_cb,
00332 (gpointer) client,
00333 NULL);
00334 g_source_attach (source, g_main_loop_get_context (client->ml));
00335 g_source_unref (source);
00336
00337 g_main_loop_run (client->ml);
00338
00339 xmms_ipc_client_destroy (client);
00340
00341 return NULL;
00342 }
00343
00344 static xmms_ipc_client_t *
00345 xmms_ipc_client_new (xmms_ipc_t *ipc, xmms_ipc_transport_t *transport)
00346 {
00347 xmms_ipc_client_t *client;
00348 GMainContext *context;
00349 int fd;
00350
00351 g_return_val_if_fail (transport, NULL);
00352
00353 client = g_new0 (xmms_ipc_client_t, 1);
00354
00355 context = g_main_context_new ();
00356 client->ml = g_main_loop_new (context, FALSE);
00357 g_main_context_unref (context);
00358
00359 fd = xmms_ipc_transport_fd_get (transport);
00360 client->iochan = g_io_channel_unix_new (fd);
00361 g_return_val_if_fail (client->iochan, NULL);
00362
00363
00364
00365
00366 g_io_channel_set_encoding (client->iochan, NULL, NULL);
00367 g_io_channel_set_buffered (client->iochan, FALSE);
00368
00369 client->transport = transport;
00370 client->ipc = ipc;
00371 client->out_msg = g_queue_new ();
00372 client->lock = g_mutex_new ();
00373
00374 return client;
00375 }
00376
00377 static void
00378 xmms_ipc_client_destroy (xmms_ipc_client_t *client)
00379 {
00380 guint i;
00381
00382 XMMS_DBG ("Destroying client!");
00383
00384 if (client->ipc) {
00385 g_mutex_lock (client->ipc->mutex_lock);
00386 client->ipc->clients = g_list_remove (client->ipc->clients, client);
00387 g_mutex_unlock (client->ipc->mutex_lock);
00388 }
00389
00390 g_main_loop_unref (client->ml);
00391 g_io_channel_unref (client->iochan);
00392
00393 xmms_ipc_transport_destroy (client->transport);
00394
00395 g_mutex_lock (client->lock);
00396 while (!g_queue_is_empty (client->out_msg)) {
00397 xmms_ipc_msg_t *msg = g_queue_pop_head (client->out_msg);
00398 xmms_ipc_msg_destroy (msg);
00399 }
00400
00401 g_queue_free (client->out_msg);
00402
00403 for (i = 0; i < XMMS_IPC_SIGNAL_END; i++) {
00404 g_list_free (client->broadcasts[i]);
00405 }
00406
00407 g_mutex_unlock (client->lock);
00408 g_mutex_free (client->lock);
00409 g_free (client);
00410 }
00411
00412
00413
00414
00415 void
00416 on_config_ipcsocket_change (xmms_object_t *object, xmmsv_t *_data, gpointer udata)
00417 {
00418 const gchar *value;
00419
00420 XMMS_DBG ("Shutting down ipc server threads through config property \"core.ipcsocket\" change.");
00421
00422 xmms_ipc_shutdown ();
00423 value = xmms_config_property_get_string ((xmms_config_property_t *) object);
00424 xmms_ipc_setup_server (value);
00425 }
00426
00427
00428
00429
00430
00431 static gboolean
00432 xmms_ipc_client_msg_write (xmms_ipc_client_t *client, xmms_ipc_msg_t *msg)
00433 {
00434 gboolean queue_empty;
00435
00436 g_return_val_if_fail (client, FALSE);
00437 g_return_val_if_fail (msg, FALSE);
00438
00439 queue_empty = g_queue_is_empty (client->out_msg);
00440 g_queue_push_tail (client->out_msg, msg);
00441
00442
00443 if (queue_empty) {
00444 GMainContext *context = g_main_loop_get_context (client->ml);
00445 GSource *source = g_io_create_watch (client->iochan, G_IO_OUT);
00446
00447 g_source_set_callback (source,
00448 (GSourceFunc) xmms_ipc_client_write_cb,
00449 (gpointer) client,
00450 NULL);
00451 g_source_attach (source, context);
00452 g_source_unref (source);
00453
00454 g_main_context_wakeup (context);
00455 }
00456
00457 return TRUE;
00458 }
00459
00460 static gboolean
00461 xmms_ipc_source_accept (GIOChannel *chan, GIOCondition cond, gpointer data)
00462 {
00463 xmms_ipc_t *ipc = (xmms_ipc_t *) data;
00464 xmms_ipc_transport_t *transport;
00465 xmms_ipc_client_t *client;
00466
00467 if (!(cond & G_IO_IN)) {
00468 xmms_log_error ("IPC listener got error/hup");
00469 return FALSE;
00470 }
00471
00472 XMMS_DBG ("Client connected");
00473 transport = xmms_ipc_server_accept (ipc->transport);
00474 if (!transport) {
00475 xmms_log_error ("accept returned null!");
00476 return TRUE;
00477 }
00478
00479 client = xmms_ipc_client_new (ipc, transport);
00480 if (!client) {
00481 xmms_ipc_transport_destroy (transport);
00482 return TRUE;
00483 }
00484
00485 g_mutex_lock (ipc->mutex_lock);
00486 ipc->clients = g_list_append (ipc->clients, client);
00487 g_mutex_unlock (ipc->mutex_lock);
00488
00489
00490
00491
00492 g_thread_create (xmms_ipc_client_thread, client, FALSE, NULL);
00493
00494 return TRUE;
00495 }
00496
00497
00498
00499
00500 gboolean
00501 xmms_ipc_setup_server_internaly (xmms_ipc_t *ipc)
00502 {
00503 g_mutex_lock (ipc->mutex_lock);
00504 ipc->chan = g_io_channel_unix_new (xmms_ipc_transport_fd_get (ipc->transport));
00505
00506 g_io_channel_set_close_on_unref (ipc->chan, TRUE);
00507 g_io_channel_set_encoding (ipc->chan, NULL, NULL);
00508 g_io_channel_set_buffered (ipc->chan, FALSE);
00509
00510 g_io_add_watch (ipc->chan, G_IO_IN | G_IO_HUP | G_IO_ERR,
00511 xmms_ipc_source_accept, ipc);
00512 g_mutex_unlock (ipc->mutex_lock);
00513 return TRUE;
00514 }
00515
00516
00517
00518
00519 gboolean
00520 xmms_ipc_has_pending (guint signalid)
00521 {
00522 GList *c, *s;
00523 xmms_ipc_t *ipc;
00524
00525 g_mutex_lock (ipc_servers_lock);
00526
00527 for (s = ipc_servers; s; s = g_list_next (s)) {
00528 ipc = s->data;
00529 g_mutex_lock (ipc->mutex_lock);
00530 for (c = ipc->clients; c; c = g_list_next (c)) {
00531 xmms_ipc_client_t *cli = c->data;
00532 g_mutex_lock (cli->lock);
00533 if (cli->pendingsignals[signalid]) {
00534 g_mutex_unlock (cli->lock);
00535 g_mutex_unlock (ipc->mutex_lock);
00536 g_mutex_unlock (ipc_servers_lock);
00537 return TRUE;
00538 }
00539 g_mutex_unlock (cli->lock);
00540 }
00541 g_mutex_unlock (ipc->mutex_lock);
00542 }
00543
00544 g_mutex_unlock (ipc_servers_lock);
00545 return FALSE;
00546 }
00547
00548 static void
00549 xmms_ipc_signal_cb (xmms_object_t *object, xmmsv_t *arg, gpointer userdata)
00550 {
00551 GList *c, *s;
00552 guint signalid = GPOINTER_TO_UINT (userdata);
00553 xmms_ipc_t *ipc;
00554 xmms_ipc_msg_t *msg;
00555
00556 g_mutex_lock (ipc_servers_lock);
00557
00558 for (s = ipc_servers; s && s->data; s = g_list_next (s)) {
00559 ipc = s->data;
00560 g_mutex_lock (ipc->mutex_lock);
00561 for (c = ipc->clients; c; c = g_list_next (c)) {
00562 xmms_ipc_client_t *cli = c->data;
00563 g_mutex_lock (cli->lock);
00564 if (cli->pendingsignals[signalid]) {
00565 msg = xmms_ipc_msg_new (XMMS_IPC_OBJECT_SIGNAL, XMMS_IPC_CMD_SIGNAL);
00566 xmms_ipc_msg_set_cookie (msg, cli->pendingsignals[signalid]);
00567 xmms_ipc_handle_cmd_value (msg, arg);
00568 xmms_ipc_client_msg_write (cli, msg);
00569 cli->pendingsignals[signalid] = 0;
00570 }
00571 g_mutex_unlock (cli->lock);
00572 }
00573 g_mutex_unlock (ipc->mutex_lock);
00574 }
00575
00576 g_mutex_unlock (ipc_servers_lock);
00577
00578 }
00579
00580 static void
00581 xmms_ipc_broadcast_cb (xmms_object_t *object, xmmsv_t *arg, gpointer userdata)
00582 {
00583 GList *c, *s;
00584 guint broadcastid = GPOINTER_TO_UINT (userdata);
00585 xmms_ipc_t *ipc;
00586 xmms_ipc_msg_t *msg = NULL;
00587 GList *l;
00588
00589 g_mutex_lock (ipc_servers_lock);
00590
00591 for (s = ipc_servers; s && s->data; s = g_list_next (s)) {
00592 ipc = s->data;
00593 g_mutex_lock (ipc->mutex_lock);
00594 for (c = ipc->clients; c; c = g_list_next (c)) {
00595 xmms_ipc_client_t *cli = c->data;
00596
00597 g_mutex_lock (cli->lock);
00598 for (l = cli->broadcasts[broadcastid]; l; l = g_list_next (l)) {
00599 msg = xmms_ipc_msg_new (XMMS_IPC_OBJECT_SIGNAL, XMMS_IPC_CMD_BROADCAST);
00600 xmms_ipc_msg_set_cookie (msg, GPOINTER_TO_UINT (l->data));
00601 xmms_ipc_handle_cmd_value (msg, arg);
00602 xmms_ipc_client_msg_write (cli, msg);
00603 }
00604 g_mutex_unlock (cli->lock);
00605 }
00606 g_mutex_unlock (ipc->mutex_lock);
00607 }
00608 g_mutex_unlock (ipc_servers_lock);
00609 }
00610
00611
00612
00613
00614 void
00615 xmms_ipc_broadcast_register (xmms_object_t *object, xmms_ipc_signals_t signalid)
00616 {
00617 g_return_if_fail (object);
00618 g_mutex_lock (ipc_object_pool_lock);
00619
00620 ipc_object_pool->broadcasts[signalid] = object;
00621 xmms_object_connect (object, signalid, xmms_ipc_broadcast_cb, GUINT_TO_POINTER (signalid));
00622
00623 g_mutex_unlock (ipc_object_pool_lock);
00624 }
00625
00626
00627
00628
00629 void
00630 xmms_ipc_broadcast_unregister (xmms_ipc_signals_t signalid)
00631 {
00632 xmms_object_t *obj;
00633
00634 g_mutex_lock (ipc_object_pool_lock);
00635 obj = ipc_object_pool->broadcasts[signalid];
00636 if (obj) {
00637 xmms_object_disconnect (obj, signalid, xmms_ipc_broadcast_cb, GUINT_TO_POINTER (signalid));
00638 ipc_object_pool->broadcasts[signalid] = NULL;
00639 }
00640 g_mutex_unlock (ipc_object_pool_lock);
00641 }
00642
00643
00644
00645
00646 void
00647 xmms_ipc_signal_register (xmms_object_t *object, xmms_ipc_signals_t signalid)
00648 {
00649 g_return_if_fail (object);
00650
00651 g_mutex_lock (ipc_object_pool_lock);
00652 ipc_object_pool->signals[signalid] = object;
00653 xmms_object_connect (object, signalid, xmms_ipc_signal_cb, GUINT_TO_POINTER (signalid));
00654 g_mutex_unlock (ipc_object_pool_lock);
00655 }
00656
00657
00658
00659
00660 void
00661 xmms_ipc_signal_unregister (xmms_ipc_signals_t signalid)
00662 {
00663 xmms_object_t *obj;
00664
00665 g_mutex_lock (ipc_object_pool_lock);
00666 obj = ipc_object_pool->signals[signalid];
00667 if (obj) {
00668 xmms_object_disconnect (obj, signalid, xmms_ipc_signal_cb, GUINT_TO_POINTER (signalid));
00669 ipc_object_pool->signals[signalid] = NULL;
00670 }
00671 g_mutex_unlock (ipc_object_pool_lock);
00672 }
00673
00674
00675
00676
00677
00678 void
00679 xmms_ipc_object_register (xmms_ipc_objects_t objectid, xmms_object_t *object)
00680 {
00681 g_mutex_lock (ipc_object_pool_lock);
00682 ipc_object_pool->objects[objectid] = object;
00683 g_mutex_unlock (ipc_object_pool_lock);
00684 }
00685
00686
00687
00688
00689 void
00690 xmms_ipc_object_unregister (xmms_ipc_objects_t objectid)
00691 {
00692 g_mutex_lock (ipc_object_pool_lock);
00693 ipc_object_pool->objects[objectid] = NULL;
00694 g_mutex_unlock (ipc_object_pool_lock);
00695 }
00696
00697
00698
00699
00700 xmms_ipc_t *
00701 xmms_ipc_init (void)
00702 {
00703 ipc_servers_lock = g_mutex_new ();
00704 ipc_object_pool_lock = g_mutex_new ();
00705 ipc_object_pool = g_new0 (xmms_ipc_object_pool_t, 1);
00706 return NULL;
00707 }
00708
00709
00710
00711
00712 void
00713 xmms_ipc_shutdown_server (xmms_ipc_t *ipc)
00714 {
00715 GList *c;
00716 xmms_ipc_client_t *co;
00717 if (!ipc) return;
00718
00719 g_mutex_lock (ipc->mutex_lock);
00720 g_source_remove_by_user_data (ipc);
00721 g_io_channel_unref (ipc->chan);
00722 xmms_ipc_transport_destroy (ipc->transport);
00723
00724 for (c = ipc->clients; c; c = g_list_next (c)) {
00725 co = c->data;
00726 if (!co) continue;
00727 co->ipc = NULL;
00728 }
00729
00730 g_list_free (ipc->clients);
00731 g_mutex_unlock (ipc->mutex_lock);
00732 g_mutex_free (ipc->mutex_lock);
00733
00734 g_free (ipc);
00735
00736 }
00737
00738
00739
00740
00741
00742 void
00743 xmms_ipc_shutdown (void)
00744 {
00745 GList *s = ipc_servers;
00746 xmms_ipc_t *ipc;
00747
00748 g_mutex_lock (ipc_servers_lock);
00749 while (s) {
00750 ipc = s->data;
00751 s = g_list_next (s);
00752 ipc_servers = g_list_remove (ipc_servers, ipc);
00753 xmms_ipc_shutdown_server (ipc);
00754 }
00755 g_mutex_unlock (ipc_servers_lock);
00756
00757 }
00758
00759
00760
00761
00762 gboolean
00763 xmms_ipc_setup_server (const gchar *path)
00764 {
00765 xmms_ipc_transport_t *transport;
00766 xmms_ipc_t *ipc;
00767 gchar **split;
00768 gint i = 0, num_init = 0;
00769 g_return_val_if_fail (path, FALSE);
00770
00771 split = g_strsplit (path, ";", 0);
00772
00773 for (i = 0; split && split[i]; i++) {
00774 ipc = g_new0 (xmms_ipc_t, 1);
00775 if (!ipc) {
00776 XMMS_DBG ("No IPC server initialized.");
00777 continue;
00778 }
00779
00780 transport = xmms_ipc_server_init (split[i]);
00781 if (!transport) {
00782 g_free (ipc);
00783 xmms_log_error ("Couldn't setup IPC listening on '%s'.", split[i]);
00784 continue;
00785 }
00786
00787
00788 ipc->mutex_lock = g_mutex_new ();
00789 ipc->transport = transport;
00790 ipc->signals = ipc_object_pool->signals;
00791 ipc->broadcasts = ipc_object_pool->broadcasts;
00792 ipc->objects = ipc_object_pool->objects;
00793
00794 xmms_ipc_setup_server_internaly (ipc);
00795 xmms_log_info ("IPC listening on '%s'.", split[i]);
00796
00797 g_mutex_lock (ipc_servers_lock);
00798 ipc_servers = g_list_prepend (ipc_servers, ipc);
00799 g_mutex_unlock (ipc_servers_lock);
00800
00801 num_init++;
00802 }
00803
00804 g_strfreev (split);
00805
00806
00807
00808 if (num_init < 1)
00809 return FALSE;
00810
00811 XMMS_DBG ("IPC setup done.");
00812 return TRUE;
00813 }
00814
00815
00816