Initializing Mercury

In this tutorial you will learn how to initialize Mercury as a client and as a server.

Initializing as a client

The following code exemplifies how to initialize Mercury as a client. We first need to call HG_Init to create an hg_class instance, then call HG_Context_create to create a context.

This code then immediately calls HG_Context_destroy and HG_Finalize to destroy the context and finalize Mercury, respectively, before terminating.

client.c (show/hide)

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <mercury.h>

static hg_class_t*     hg_class     = NULL; /* Pointer to the Mercury class */
static hg_context_t*   hg_context   = NULL; /* Pointer to the Mercury context */

int main(int argc, char** argv)
{
    hg_return_t ret;
    /*
     * Initialize an hg_class.
     * Here we only specify the protocal since this is a client
     * (no need for an address and a port). HG_FALSE indicates that
     * the client will not listen for incoming requests.
     */
    hg_class = HG_Init("tcp", HG_FALSE);
    assert(hg_class != NULL);

    /* Creates a context for the hg_class. */
    hg_context = HG_Context_create(hg_class);
    assert(hg_context != NULL);

    /* Destroy the context. */
    ret = HG_Context_destroy(hg_context);
    assert(ret == HG_SUCCESS);

    /* Finalize the hg_class. */
    hg_return_t err = HG_Finalize(hg_class);
    assert(err == HG_SUCCESS);
    return 0;
}

Initializing as a server

The following code exemplifies how to initialize Mercury as a server. Just like for a client, we call HG_Init and HG_Context_create, but this time we pass HG_TRUE to HG_Init to indicate that this process is going to listen for incoming requests.

server.c (show/hide)

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <mercury.h>

static hg_class_t*     hg_class   = NULL; /* the mercury class */
static hg_context_t*   hg_context = NULL; /* the mercury context */

int main(int argc, char** argv)
{
    hg_return_t ret;

    /* Initialize Mercury and get an hg_class handle.
     * bmi+tcp is the protocol to use.
     * localhost is the address of the server (not useful at the server itself).
     * HG_TRUE is here to specify that mercury will listen for incoming requests.
     * (HG_TRUE on servers, HG_FALSE on clients).
     */
    hg_class = HG_Init("tcp", HG_TRUE);
    assert(hg_class != NULL);

    /* Get the address of the server */
    char hostname[128];
    hg_size_t hostname_size = 128;
    hg_addr_t self_addr;
    HG_Addr_self(hg_class, &self_addr);
    HG_Addr_to_string(hg_class, hostname, &hostname_size, self_addr);
    printf("Server running at address %s\n",hostname);
    HG_Addr_free(hg_class, self_addr);

    /* Creates a Mercury context from the Mercury class. */
    hg_context = HG_Context_create(hg_class);
    assert(hg_context != NULL);

    /* Progress loop */
    do
    {
        /* count will keep track of how many RPCs were treated in a given
         * call to HG_Trigger.
         */
        unsigned int count;
        do {
            /* Executes callbacks.
             * 0 = no timeout, the function just returns if there is nothing to process.
             * 1 = the max number of callbacks to execute before returning.
             * After the call, count will hold the number of callbacks executed.
             */
            ret = HG_Trigger(hg_context, 0, 1, &count);
        } while((ret == HG_SUCCESS) && count);
        /* Exit the loop if no event has been processed. */

        /* Make progress on receiving/sending data.
         * 100 is the timeout in milliseconds, for which to wait for network events. */
        HG_Progress(hg_context, 100);
    } while(1); /* another condition should be put here for the loop to terminate */

    /* Destroys the Mercury context. */
    ret = HG_Context_destroy(hg_context);
    assert(ret == HG_SUCCESS);

    /* Finalize Mercury. */
    ret = HG_Finalize(hg_class);
    assert(ret == HG_SUCCESS);

    return 0;
}

This code also exemplifies a typical Mercury progress loop. This progress loop alternates HG_Progress, which makes progress on network events (sending and receiving data), and HG_Trigger, which calls registered callbacks based on the events that happened in HG_Progress.

Note

Since this server does not expose any RPC yet, it will just keep running until you kill it.