WL#12003: Component interface to deliver signals to the host application

Affects: Server-8.0   —   Status: Complete

The replication components need to be able to shut down the server.

This worklog adds a component service to send signals to the hosting binary.
One of these signals is the shutdown signal.
FRQ1: A new component signal service will be added to deliver signals to the
implementor of the service.
FRQ2: the server binary will implement the signal service to react to the
signals delivered by it.
FRQ3: A convenience C++ wrapper will be added to the signal service that covers
each signal and takes the right argument types for that signal.
FRQ4: A signal will be implemented into the signal service that will signal that
the main application needs to shut down.
FRQ4.1: The server implementation of the shutdown signal will invoke the normal
shutdown procedure for the server.
FRQ4.2: The shutdown signal will have its effect regardless of the state the
server is in during bootstrap, even in a plugin initialization or a component
initialization
FRQ4.3: the shutdown signal will work equally well regardless of the origin of
it being called: a plugin or a component.
FRQ4.4: A message will first be logged to the serer log when the shutdown signal
is received by the server binary
FRQ5. Except for the above special cases, the service will behave exactly as the
SQL shutdown command. 
enum {
  HOST_APPLICATION_SIGNAL_SHUTDOWN = 0,  // shut down. No argument
  HOST_APPLICATION_SIGNAL_LAST = 1       // keep that last
};
/**
  A service to deliver a signal to host application.

  Typically there'll be just one implementation of this by the main application.
  Other parties interested in listening to shutdown may override the
  implementation with a broadcast one and have multiple implementations
  receiving the shutdown signal
*/
BEGIN_SERVICE_DEFINITION(host_application_signal)
/**
  Send a signal

  Currently supported signals:
    \ref HOST_APPLICATION_SIGNAL_SHUTDOWN

  @param signal_no The signal to trigger
  @param arg Signal dependent argument
  @return Status of performed operation
  @retval false success (valid password)
  @retval true failure (invalid password)
*/
DECLARE_BOOL_METHOD(signal, (int signal_no, void *arg));

END_SERVICE_DEFINITION(host_application_signal)

/** template to simplify sending application signals */
template 
bool my_host_application_signal(SERVICE_TYPE(registry) * registry,
                                arg_type argument) {
  my_service host_app(
      "host_application_signal", registry);

  return host_app->signal(signal_number, argument);
}

/** 
  Ease of use utility function to call the @ref HOST_APPLICATION_SIGNAL_SHUTDOWN
  signal

  @sa host_application_signal

  @param registry the registry handle to use
  @retval true failure
  @retval false success
*/
inline bool my_host_application_signal_shutdown(SERVICE_TYPE(registry) * registry) {
  return my_host_application_signal(registry, NULL);
}

BEGIN_SERVICE_IMPLEMENTATION(mysql_server, host_application_signal)
mysql_component_host_application_signal_imp::signal
END_SERVICE_IMPLEMENTATION();
The implementation of the shutdown signal will basically log a message to the
syslog and call kill_mysql() to provoke a normal shutdown.

A test UDF in its separate component will be added to allow invocation of the
host shutdown signal.

The server's initialization sequence needs mending since one can't call
kill_mysql() before the "signal" thread is initialized. Thus added a new flag
that will be set by kill_mysql() when called before the server is initialized
and the mysqld main function will check that flag once it initializes the sever
to initiate shutdown if the flag is on.

Added a test plugin to verify that a service can be called at plugin initialization.


Using the service

The service will be usable if there's access to the registry and there's an
implementation of it. The server component will be the one providing the default
implementation for mysqld. So once this is initialized one can use the service.

First of all you'll need a registry reference. This can be procured in the usual
way:
1. by mysql_plugin_registry_acquire() (for plugins)
2. as an explicit reference by BEGIN_COMPONENT_REQUIRES() (for components).

There are two alternative ways of calling the signal function:
1. Using the raw service:
  #include 
  #include 

  my_service host_app(
        "host_application_signal", mysql_service_registry);
  host_app->signal(HOST_APPLICATION_SIGNAL_SHUTDOWN, NULL);

2. Using the convenience wrapper provided by this worklog's
my_host_application_signal.h:

#include 
my_host_application_signal_shutdown(mysql_service_registry);