Yuki Lau
Yuki Lau

Reputation: 21

The RPC svc_run() function returned in a pthread

Question statement

I am developing an RPC program, using the rpcgen tool to generate the template codes. In the generated _srv.c file, the main() function does the initialization work and calls the svc_run() to wait for RPC requests to arrive. The main() code is below.

int
main (int argc, char **argv)
{
    register SVCXPRT *transp;

    pmap_unset (SDFS_PROG, SDFS_VERS_1);

    transp = svcudp_create(RPC_ANYSOCK);
    if (transp == NULL) {
        fprintf (stderr, "%s", "cannot create udp service.");
        exit(1);
    }
    if (!svc_register(transp, SDFS_PROG, SDFS_VERS_1, sdfs_prog_1, IPPROTO_UDP)) {
        fprintf (stderr, "%s", "unable to register (SDFS_PROG, SDFS_VERS_1, udp).");
        exit(1);
    }

    transp = svctcp_create(RPC_ANYSOCK, 0, 0);
    if (transp == NULL) {
        fprintf (stderr, "%s", "cannot create tcp service.");
        exit(1);
    }
    if (!svc_register(transp, SDFS_PROG, SDFS_VERS_1, sdfs_prog_1, IPPROTO_TCP)) {
        fprintf (stderr, "%s", "unable to register (SDFS_PROG, SDFS_VERS_1, tcp).");
        exit(1);
    }

    svc_run ();
    fprintf (stderr, "%s", "svc_run returned");
    exit (1);
    /* NOTREACHED */
}

Theoretically, the svc_run() never returns, just to wait for RPC requests. And now, I wish to reconstruct the codes above, by putting them in a function, and creating a pthread to wait for the RPC requests. The reconstructed code is below.

static pthread_t sdfs_prog_srv_fd;
static void * 
sdfs_prog_srv_run_thread(){
    svc_run ();
    perror("sdfs rpc server thread start failed");
    return NULL;
}

void 
sdfs_prog_srv_run(){
    register SVCXPRT *transp;
    pmap_unset (SDFS_PROG, SDFS_VERS_1);

    transp = svcudp_create(RPC_ANYSOCK);
    if (transp == NULL) {
        fprintf (stderr, "%s", "cannot create udp service.");
        exit(1);
    }
    if (!svc_register(transp, SDFS_PROG, SDFS_VERS_1, sdfs_prog_1, IPPROTO_UDP)) {
        fprintf (stderr, "%s", "unable to register (SDFS_PROG, SDFS_VERS_1, udp).");
        exit(1);
    }

    transp = svctcp_create(RPC_ANYSOCK, 0, 0);
    if (transp == NULL) {
        fprintf (stderr, "%s", "cannot create tcp service.");
        exit(1);
    }
    if (!svc_register(transp, SDFS_PROG, SDFS_VERS_1, sdfs_prog_1, IPPROTO_TCP)) {
        fprintf (stderr, "%s", "unable to register (SDFS_PROG, SDFS_VERS_1, tcp).");
        exit(1);
    }
    if(pthread_create(&sdfs_prog_srv_fd, NULL, sdfs_prog_srv_run_thread, NULL)){
        fprintf (stderr, "%s", "unable to create rcp srv thread");
    }
}

However, when I run the program, the svc_run() just returned and print info sdfs rpc server thread start failed in the terminal, which is not what I want.

So I am curious about why this happened and how can I run the RPC svc in background?

Methods I have tried

I have tried some methods but with no avail.

Method 1: change the SVCXPRT *transp into a global variable

I am not familiar with the RPC mechanism and its code. I just thought the svc_run() may use some variables, and the former functions like svc_register() used the transp, but it's a local variable with a register type and will be released when the function ends. So I assumed the single svc_run() in the pthread might not be able to access the relevant variable. I claimed the transp as a global variable like:

SVCXPRT *transp;
static void * 
sdfs_prog_srv_run_thread(){
    svc_run ();
    perror("sdfs rpc server thread start failed");
    return NULL;
}

But is doesn't work.

Method 2: do not put the svc_run() in the pthread

I tried not to put the svc_run() in the pthread, like:

    if (!svc_register(transp, SDFS_PROG, SDFS_VERS_1, sdfs_prog_1, IPPROTO_TCP)) {
        fprintf (stderr, "%s", "unable to register (SDFS_PROG, SDFS_VERS_1, tcp).");
        exit(1);
    }
    svc_run ();
    perror("sdfs rpc server thread start failed");

The svc_run() did not return and was blocked to wait for requests, but this is not what I want.

Upvotes: 1

Views: 37

Answers (0)

Related Questions