View | Details | Raw Unified | Return to bug 802525
Collapse All | Expand All

(-)a/dbus/dbus-bus.c (-13 / +149 lines)
Lines 421-426 _dbus_bus_notify_shared_connection_disconnected_unlocked (DBusConnection *connec Link Here
421
  _DBUS_UNLOCK (bus);
421
  _DBUS_UNLOCK (bus);
422
}
422
}
423
423
424
static dbus_bool_t
425
internal_register (DBusConnection *connection,
426
                   int             timeout_milliseconds,
427
                   DBusError      *error)
428
{
429
  DBusMessage *message, *reply;
430
  char *name;
431
  BusData *bd;
432
  dbus_bool_t retval;
433
434
  _dbus_return_val_if_fail (connection != NULL, FALSE);
435
  _dbus_return_val_if_error_is_set (error, FALSE);
436
437
  retval = FALSE;
438
  message = NULL;
439
  reply = NULL;
440
441
  _DBUS_LOCK (bus_datas);
442
443
  bd = ensure_bus_data (connection);
444
  if (bd == NULL)
445
    {
446
      _DBUS_SET_OOM (error);
447
      goto out;
448
    }
449
450
  if (bd->unique_name != NULL)
451
    {
452
      _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n",
453
                     bd->unique_name);
454
      /* Success! */
455
      retval = TRUE;
456
      goto out;
457
    }
458
  
459
  message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
460
                                          DBUS_PATH_DBUS,
461
                                          DBUS_INTERFACE_DBUS,
462
                                          "Hello"); 
463
464
  if (!message)
465
    {
466
      _DBUS_SET_OOM (error);
467
      goto out;
468
    }
469
  
470
  reply = dbus_connection_send_with_reply_and_block (connection, message, timeout_milliseconds, error);
471
472
  if (reply == NULL)
473
    goto out;
474
  else if (dbus_set_error_from_message (error, reply))
475
    goto out;
476
  else if (!dbus_message_get_args (reply, error,
477
                                   DBUS_TYPE_STRING, &name,
478
                                   DBUS_TYPE_INVALID))
479
    goto out;
480
  
481
  bd->unique_name = _dbus_strdup (name);
482
  if (bd->unique_name == NULL)
483
    {
484
      _DBUS_SET_OOM (error);
485
      goto out;
486
    }
487
  
488
  retval = TRUE;
489
  
490
 out:
491
  _DBUS_UNLOCK (bus_datas);
492
493
  if (message)
494
    dbus_message_unref (message);
495
496
  if (reply)
497
    dbus_message_unref (reply);
498
499
  return retval;
500
}
501
502
static DBusConnection *
503
internal_open_and_register (const char *address, dbus_bool_t private, int timeout_milliseconds, DBusError *error)
504
{
505
  DBusConnection *connection;
506
507
  if (private)
508
    connection = dbus_connection_open_private (address, error);
509
  else
510
    connection = dbus_connection_open (address, error);
511
512
  if (!connection)
513
    {
514
      goto out;
515
    }
516
517
  if (!internal_register (connection, timeout_milliseconds, error))
518
    {
519
      _dbus_connection_close_possibly_shared (connection);
520
      dbus_connection_unref (connection);
521
      connection = NULL;
522
      goto out;
523
    }
524
525
out:
526
  return connection;
527
}
528
529
/* When the D-Bus upgrade that moves /var/run/dbus/ to /run/dbus/ is applied,
530
 * D-Bus cannot be restarted with the new socket in /run/, because the session
531
 * wouldn't be able to cope with it. We end up with a daemon listening on
532
 * /var/run/dbus/system_bus_socket, but clients will now try to register
533
 * with it on /run/dbus/system_bus_socket, causing the upgrade, and eventually
534
 * critical parts of the user's session, to hang.
535
 *
536
 * The workaround is inelegant, but probably good enough: We allow the initial
537
 * attempt to time out quickly and fall back to trying the old default address.
538
 * If that fails too, we go back to blocking on the initial address. */
539
540
#define OLD_SYSTEM_BUS_DEFAULT_ADDRESS "unix:path=/var/run/dbus/system_bus_socket"
541
#define INITIAL_TIMEOUT_MILLISECONDS 250
542
#define INCREMENT_TIMEOUT_MILLISECONDS 250
543
#define MAX_TIMEOUT_MILLISECONDS 10000
544
545
static DBusConnection *
546
internal_open_and_register_with_fallback (const char *address, dbus_bool_t private, DBusError *error)
547
{
548
  DBusConnection *connection = NULL;
549
  int timeout_milliseconds;
550
551
  for (timeout_milliseconds = INITIAL_TIMEOUT_MILLISECONDS;
552
       connection == NULL && timeout_milliseconds < MAX_TIMEOUT_MILLISECONDS;
553
       timeout_milliseconds += INCREMENT_TIMEOUT_MILLISECONDS)
554
    {
555
      connection = internal_open_and_register (address, private, timeout_milliseconds, NULL);
556
557
      if (!connection && !strcmp (address, DBUS_SYSTEM_BUS_DEFAULT_ADDRESS))
558
          connection = internal_open_and_register (OLD_SYSTEM_BUS_DEFAULT_ADDRESS, private, timeout_milliseconds, NULL);
559
    }
560
561
  if (!connection)
562
    {
563
      /* We couldn't register with any of the sockets; fall back to original behavior, blocking
564
       * forever or returning an error. */
565
      connection = internal_open_and_register (address, private, -1, error);
566
    }
567
568
  return connection;
569
}
570
424
static DBusConnection *
571
static DBusConnection *
425
internal_bus_get (DBusBusType  type,
572
internal_bus_get (DBusBusType  type,
426
                  dbus_bool_t  private,
573
                  dbus_bool_t  private,
Lines 474-494 internal_bus_get (DBusBusType type, Link Here
474
      goto out;
621
      goto out;
475
    }
622
    }
476
623
477
  if (private)
624
  connection = internal_open_and_register_with_fallback (address, private, error);
478
    connection = dbus_connection_open_private (address, error);
479
  else
480
    connection = dbus_connection_open (address, error);
481
  
482
  if (!connection)
483
    {
484
      goto out;
485
    }
486
625
487
  if (!dbus_bus_register (connection, error))
626
  if (!connection)
488
    {
627
    {
489
      _dbus_connection_close_possibly_shared (connection);
490
      dbus_connection_unref (connection);
491
      connection = NULL;
492
      goto out;
628
      goto out;
493
    }
629
    }
494
630
(-)a/dbus/dbus-connection.c (-6 / +27 lines)
Lines 348-354 static void _dbus_connection_update_dispatch_status_and_unlock (DB Link Here
348
static void               _dbus_connection_last_unref                        (DBusConnection     *connection);
348
static void               _dbus_connection_last_unref                        (DBusConnection     *connection);
349
static void               _dbus_connection_acquire_dispatch                  (DBusConnection     *connection);
349
static void               _dbus_connection_acquire_dispatch                  (DBusConnection     *connection);
350
static void               _dbus_connection_release_dispatch                  (DBusConnection     *connection);
350
static void               _dbus_connection_release_dispatch                  (DBusConnection     *connection);
351
static DBusDispatchStatus _dbus_connection_flush_unlocked                    (DBusConnection     *connection);
351
static DBusDispatchStatus _dbus_connection_flush_unlocked                    (DBusConnection     *connection, int timeout_milliseconds);
352
static void               _dbus_connection_close_possibly_shared_and_unlock  (DBusConnection     *connection);
352
static void               _dbus_connection_close_possibly_shared_and_unlock  (DBusConnection     *connection);
353
static dbus_bool_t        _dbus_connection_get_is_connected_unlocked         (DBusConnection     *connection);
353
static dbus_bool_t        _dbus_connection_get_is_connected_unlocked         (DBusConnection     *connection);
354
static dbus_bool_t        _dbus_connection_peek_for_reply_unlocked           (DBusConnection     *connection,
354
static dbus_bool_t        _dbus_connection_peek_for_reply_unlocked           (DBusConnection     *connection,
Lines 2367-2373 _dbus_connection_block_pending_call (DBusPendingCall *pending) Link Here
2367
  DBusConnection *connection;
2367
  DBusConnection *connection;
2368
  dbus_uint32_t client_serial;
2368
  dbus_uint32_t client_serial;
2369
  DBusTimeout *timeout;
2369
  DBusTimeout *timeout;
2370
  int timeout_milliseconds, elapsed_milliseconds;
2370
  int timeout_milliseconds = -1, elapsed_milliseconds;
2371
2371
2372
  _dbus_assert (pending != NULL);
2372
  _dbus_assert (pending != NULL);
2373
2373
Lines 2379-2385 _dbus_connection_block_pending_call (DBusPendingCall *pending) Link Here
2379
  connection = _dbus_pending_call_get_connection_and_lock (pending);
2379
  connection = _dbus_pending_call_get_connection_and_lock (pending);
2380
  
2380
  
2381
  /* Flush message queue - note, can affect dispatch status */
2381
  /* Flush message queue - note, can affect dispatch status */
2382
  _dbus_connection_flush_unlocked (connection);
2382
2383
  timeout = _dbus_pending_call_get_timeout_unlocked (pending);
2384
  if (timeout)
2385
    timeout_milliseconds = dbus_timeout_get_interval (timeout);
2386
2387
  _dbus_connection_flush_unlocked (connection, timeout_milliseconds);
2383
2388
2384
  client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
2389
  client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
2385
2390
Lines 3555-3561 dbus_connection_send_with_reply_and_block (DBusConnection *connection, Link Here
3555
 * @param connection the connection.
3560
 * @param connection the connection.
3556
 */
3561
 */
3557
static DBusDispatchStatus
3562
static DBusDispatchStatus
3558
_dbus_connection_flush_unlocked (DBusConnection *connection)
3563
_dbus_connection_flush_unlocked (DBusConnection *connection, int timeout_milliseconds)
3559
{
3564
{
3560
  /* We have to specify DBUS_ITERATION_DO_READING here because
3565
  /* We have to specify DBUS_ITERATION_DO_READING here because
3561
   * otherwise we could have two apps deadlock if they are both doing
3566
   * otherwise we could have two apps deadlock if they are both doing
Lines 3563-3582 _dbus_connection_flush_unlocked (DBusConnection *connection) Link Here
3563
   * dispatch status.
3568
   * dispatch status.
3564
   */
3569
   */
3565
  DBusDispatchStatus status;
3570
  DBusDispatchStatus status;
3571
  long start_tv_sec, start_tv_usec;
3572
  long tv_sec, tv_usec;
3573
  int elapsed_milliseconds = 0;
3566
3574
3567
  HAVE_LOCK_CHECK (connection);
3575
  HAVE_LOCK_CHECK (connection);
3576
3577
  _dbus_get_monotonic_time (&start_tv_sec, &start_tv_usec);
3568
  
3578
  
3569
  while (connection->n_outgoing > 0 &&
3579
  while (connection->n_outgoing > 0 &&
3570
         _dbus_connection_get_is_connected_unlocked (connection))
3580
         _dbus_connection_get_is_connected_unlocked (connection))
3571
    {
3581
    {
3572
      _dbus_verbose ("doing iteration in\n");
3582
      _dbus_verbose ("doing iteration in\n");
3583
3584
      if (timeout_milliseconds >= 0)
3585
        {
3586
          _dbus_get_monotonic_time (&tv_sec, &tv_usec);
3587
          elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
3588
            (tv_usec - start_tv_usec) / 1000;
3589
3590
          if (elapsed_milliseconds >= timeout_milliseconds)
3591
            break;
3592
        }
3593
3573
      HAVE_LOCK_CHECK (connection);
3594
      HAVE_LOCK_CHECK (connection);
3574
      _dbus_connection_do_iteration_unlocked (connection,
3595
      _dbus_connection_do_iteration_unlocked (connection,
3575
                                              NULL,
3596
                                              NULL,
3576
                                              DBUS_ITERATION_DO_READING |
3597
                                              DBUS_ITERATION_DO_READING |
3577
                                              DBUS_ITERATION_DO_WRITING |
3598
                                              DBUS_ITERATION_DO_WRITING |
3578
                                              DBUS_ITERATION_BLOCK,
3599
                                              DBUS_ITERATION_BLOCK,
3579
                                              -1);
3600
                                              timeout_milliseconds - elapsed_milliseconds);
3580
    }
3601
    }
3581
3602
3582
  HAVE_LOCK_CHECK (connection);
3603
  HAVE_LOCK_CHECK (connection);
Lines 3606-3612 dbus_connection_flush (DBusConnection *connection) Link Here
3606
  
3627
  
3607
  CONNECTION_LOCK (connection);
3628
  CONNECTION_LOCK (connection);
3608
3629
3609
  status = _dbus_connection_flush_unlocked (connection);
3630
  status = _dbus_connection_flush_unlocked (connection, -1);
3610
  
3631
  
3611
  HAVE_LOCK_CHECK (connection);
3632
  HAVE_LOCK_CHECK (connection);
3612
  /* Unlocks and calls out to user code */
3633
  /* Unlocks and calls out to user code */

Return to bug 802525