margo-example-mp-server.c 4.39 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
/*
 * (C) 2015 The University of Chicago
 * 
 * See COPYRIGHT in top-level directory.
 */

#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <abt.h>
#include <margo.h>
12
#include <margo-config.h>
Philip Carns's avatar
Philip Carns committed
13 14
#include "svc1-server.h"
#include "svc2-server.h"
15 16 17 18 19 20 21 22 23 24 25 26 27

/* example server program that starts a skeleton for sub-services within
 * this process to register with
 */

/* this is a "common" rpc that is handled by the core daemon
 */

static void my_rpc_shutdown_ult(hg_handle_t handle)
{
    hg_return_t hret;
    margo_instance_id mid;

28
    //printf("Got RPC request to shutdown\n");
29

30
    mid = margo_hg_handle_get_instance(handle);
31
    assert(mid != MARGO_INSTANCE_NULL);
32

33
    hret = margo_respond(handle, NULL);
34 35
    assert(hret == HG_SUCCESS);

36
    margo_destroy(handle);
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52

    /* NOTE: we assume that the server daemon is using
     * margo_wait_for_finalize() to suspend until this RPC executes, so there
     * is no need to send any extra signal to notify it.
     */
    margo_finalize(mid);

    return;
}
DEFINE_MARGO_RPC_HANDLER(my_rpc_shutdown_ult)


int main(int argc, char **argv) 
{
    int ret;
    margo_instance_id mid;
53
    hg_return_t hret;
54 55 56
    hg_addr_t addr_self;
    char addr_self_string[128];
    hg_size_t addr_self_string_sz = 128;
57 58
    ABT_xstream svc1_xstream2;
    ABT_pool svc1_pool2;
59
    ABT_pool handler_pool;
60 61 62 63 64 65 66 67

    if(argc != 2)
    {
        fprintf(stderr, "Usage: ./server <listen_addr>\n");
        fprintf(stderr, "Example: ./server na+sm://\n");
        return(-1);
    }

68 69 70
    /* actually start margo -- this step encapsulates the Mercury and
     * Argobots initialization and must precede their use */
    /* Use the calling xstream to drive progress and execute handlers. */
71
    /***************************************/
72 73
    mid = margo_init(argv[1], MARGO_SERVER_MODE, 0, -1);
    if(mid == MARGO_INSTANCE_NULL)
74
    {
75
        fprintf(stderr, "Error: margo_init()\n");
76 77 78 79
        return(-1);
    }

    /* figure out what address this server is listening on */
80 81
    hret = margo_addr_self(mid, &addr_self);
    if(hret != HG_SUCCESS)
82
    {
83 84
        fprintf(stderr, "Error: margo_addr_self()\n");
        margo_finalize(mid);
85 86
        return(-1);
    }
87 88
    hret = margo_addr_to_string(mid, addr_self_string, &addr_self_string_sz, addr_self);
    if(hret != HG_SUCCESS)
89
    {
90 91 92
        fprintf(stderr, "Error: margo_addr_to_string()\n");
        margo_addr_free(mid, addr_self);
        margo_finalize(mid);
93 94
        return(-1);
    }
95
    margo_addr_free(mid, addr_self);
96

97
    printf("# accepting RPCs on address \"%s\"\n", addr_self_string);
98

99 100 101
    /* register RPCs and services */
    /***************************************/

102 103 104
    /* register a shutdown RPC as just a generic handler; not part of a
     * multiplexed service
     */
105
    MARGO_REGISTER(mid, "my_shutdown_rpc", void, void, my_rpc_shutdown_ult);
106

Philip Carns's avatar
Philip Carns committed
107
    /* register svc1, with provider_id 1, to execute on the default handler pool
108 109
     * used by Margo
     */
110 111
    margo_get_handler_pool(mid, &handler_pool);
    ret = svc1_register(mid, handler_pool, 1);
112 113
    assert(ret == 0);

114
    /* create a dedicated xstream and pool for another instance of svc1 */
115 116 117 118
	ret = ABT_xstream_create(ABT_SCHED_NULL, &svc1_xstream2);
	assert(ret == 0);
	ret = ABT_xstream_get_main_pools(svc1_xstream2, 1, &svc1_pool2);
	assert(ret == 0);
Shane Snyder's avatar
Shane Snyder committed
119

Philip Carns's avatar
Philip Carns committed
120
    /* register svc1, with provider_id 2, to execute on a separate pool.  This
121 122 123 124 125 126
     * will result in svc1 being registered twice, with the client being able
     * to dictate which instance they want to target
     */
    ret = svc1_register(mid, svc1_pool2, 2);
    assert(ret == 0);

Philip Carns's avatar
Philip Carns committed
127
    /* register svc2, with provider_id 3, to execute on the default handler pool
128 129
     * used by Margo
     */
130 131
    margo_get_handler_pool(mid, &handler_pool);
    ret = svc2_register(mid, handler_pool, 3);
132 133 134 135
    assert(ret == 0);

    /* shut things down */
    /****************************************/
136

137 138 139 140 141 142 143
    /* NOTE: there isn't anything else for the server to do at this point
     * except wait for itself to be shut down.  The
     * margo_wait_for_finalize() call here yields to let Margo drive
     * progress until that happens.
     */
    margo_wait_for_finalize(mid);

144
    /*  TODO: rethink this; can't touch mid or use ABT after wait for finalize */
Philip Carns's avatar
Philip Carns committed
145
#if 0
Philip Carns's avatar
Philip Carns committed
146 147 148
    svc1_deregister(mid, *handler_pool, 1);
    svc1_deregister(mid, svc1_pool2, 2);
    svc2_deregister(mid, *handler_pool, 3);
149 150 151

    ABT_xstream_join(svc1_xstream2);
    ABT_xstream_free(&svc1_xstream2);
152
#endif
153 154 155 156

    return(0);
}