If your protocol includes a "goodbye" message:

  1. Send the "goodbye" message.
  2. Set the wheel's FlushedEvent handler.
  3. Destroy the wheel in the FlushedEvent handler.

$heap->{wheel_client}->put("goodbye");
$heap->{wheel_client}->event(FlushedEvent => 'close_wheel_client');

sub close_wheel_client {
  my $heap = $_[HEAP];
  delete $heap->{wheel_client};
}

If your protocol does not include a "goodbye" message:

  1. Check the return value of the wheel's get_driver_out_octets() method when requesting a shutdown.
    1. If it's zero, go ahead and destroy the wheel.
    2. If it's nonzero, set the wheel's FlushedEvent handler.
  2. Destroy the wheel in the FlushedEvent handler.

if ($heap->{wheel_client}->get_driver_out_octets() > 0) {
  $heap->{wheel_client}->event(FlushedEvent => 'close_wheel_client');
}
else {
  delete $heap->{wheel_client};
}

sub close_wheel_client {
  my $heap = $_[HEAP];
  delete $heap->{wheel_client};
}

The second method will also work if you have goodbye messages, but get_driver_out_octets() will always be nonzero.

On the other hand, if put() ever flushes right away, the second method may be the only one that works reliably.