def <<(message)
      message = Message.coerce(message)

      if TERM == message[0]
        # NOTE: can't just send this to the actor. The sender might call
        # #terminate immediately, which most likely causes a hang due to race
        # conditions.
        terminate
      else
        begin
          @mtx.synchronize do
            raise DeadActorError if not @running
            message.send_to(self)
          end
        rescue IO::EAGAINWaitWritable
          # The sndtimeo has been reached.
          #
          # This should fix the race condition (mainly on JRuby) between
          # @running not being set to false yet but the actor handler already
          # terminating and thus not able to receive messages anymore.
          #
          # This shouldn't result in an infinite loop, since it'll stop as
          # soon as @running is set to false by #signal_shimmed_handler_death,
          # at least when using a Ruby handler.
          #
          # In case of a C function handler, it MUST NOT crash and only
          # terminate when being sent the "$TERM" message using #terminate (so
          # #await_handler_death can set
          # @running to false).
          retry
        end
      end
      self
    end
def <<(message)
      message = Message.coerce(message)

      if TERM == message[0]
        # NOTE: can't just send this to the actor. The sender might call
        # #terminate immediately, which most likely causes a hang due to race
        # conditions.
        terminate
      else
        begin
          @mtx.synchronize do
            raise DeadActorError if not @running
            message.send_to(self)
          end
        rescue IO::EAGAINWaitWritable
          # The sndtimeo has been reached.
          #
          # This should fix the race condition (mainly on JRuby) between
          # @running not being set to false yet but the actor handler already
          # terminating and thus not able to receive messages anymore.
          #
          # This shouldn't result in an infinite loop, since it'll stop as
          # soon as @running is set to false by #signal_shimmed_handler_death,
          # at least when using a Ruby handler.
          #
          # In case of a C function handler, it MUST NOT crash and only
          # terminate when being sent the "$TERM" message using #terminate (so
          # #await_handler_death can set
          # @running to false).
          retry
        end
      end
      self
    end
Creates a new actor. Either pass a callback directly or a block. The
 block will be called for every received message.

 In case the given callback is an FFI::Pointer (to a C function), it's
 used as-is. It is expected to do the handshake (signal) itself.

 @param callback [FFI::Pointer, Proc, #call] pointer to a C function or
   just anything callable
 @param c_args [FFI::Pointer, nil] args, only useful if callback is an
   FFI::Pointer
 @yieldparam message [Message]
 @yieldparam pipe [Socket::PAIR]
 @see #process_messages
 Send a message to the actor.
 @param message [Object] message to send to the actor, see {Message.coerce}
 @return [self] so it's chainable
 @raise [DeadActorError] if actor is terminated
 @raise [IO::EAGAINWaitWritable, RuntimeError] anything that could be
   raised by {Message#send_to}
 @note Normally this method is asynchronous, but if the message is
   "$TERM", it blocks until the actor is terminated.