Reputation: 21
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?
I have tried some methods but with no avail.
SVCXPRT *transp
into a global variableI 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.
svc_run()
in the pthreadI 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