This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: C integrated RPC


In attach you can find example program,
client and server side. And doc for the system as README file.
The newest version of the sources can be downloaded from
crpc at sf dot net.

To compile the package just 'make' and 'make install'. Tests can be
found inside the tests
directory.

There are several differences between CRPC and traditinal RPC systems.
So it has no discriptive language like IDL, everything needed is taken
from the C code.
The goal of the system is to be as easy as possible.

With CRPC you do not need to give static identifiers for remote
functions, you should only
use two new modificators - __remote (to declare client function) and __local
(to declare server function). ID for the function will be computed by
wrapper compiler, as
32-bit checksum of function prototype text. With CRPC you don't need to pack
data before sending trough the net, every thing is automatically. Also CRPC
can work with pointer addressed data, I added a special __attribute__ statement,
which can tell the size addressed by the pointer. CRPC can send any data types,
any structs.

Also __in and __out modificators are available for the function
parameters, which tells
the system to send data only to the server or only fill some array on
the server. The default
mode is to send data to the server, change it there and get it back on client.

CRPC wrapper compiler can work with make and can be used 'instead' of
the GCC, as it
covers it. The wrapper compiler works between the preprocessor and
main C compiler.
Shared libraries can be biuld with this compiler. Also such __remote
functions can be
used with another servers, for example apache. (In the package there
is an example with
apache).

The client side is look like an orinary application, all __remote
function is like extern.
The server side is more looks like as library, it must not have main.
C-wrapper compiler will generate all the needed code the client and server.

CRPC can be compiled on Linux and FreeBSD. It needs only libc (and
POSIX Threads now
either). The parser system is uses is written only in C. I tried to do
it as fast as it was possible.

So CRPC is something like a C extension, which I think will be more effective if
it will be a part of the C compiler.

One more difference is that CRPC can easily 'refactor' an existing
non-network application.
You only need to add __remote modificators to function prototypes and
recompile the source
and will get network application.

Also I am working the the threaded functions, mutual variables (POSIX
Threads support).
Have plans to add crypto support based on something like ssh.
/*
 * Copyright (c) 2006-2008 by Andrey V. Babanin <ababanin@gmail.com>.
 * All rights reserved.
 *
 * Please see COPYRIGHT.
 *
 * $Id: clnt.c,v 1.4 2008/02/06 17:13:22 granica_raydom Exp $
 */

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void __remote init_task(void);
__remote void checkto (double data[3]);
__remote short signed int
perform_task(unsigned int __in *mode,
unsigned int __out *data,int s)
__attribute((__format_ptr(0[2],1[2])));
__remote double check(unsigned int *);
__remote unsigned int  mul(unsigned int lim);
int __remote _av(char **a,int n)
__attribute__((__format_ptr(0[1])));
int __remote _req(char *a);
void __remote _req2(char __in *sreq);
int __remote _req3(char __out sreq[100]);
int __remote _req4(char sreq[50]);

int main(int argc,char **argv) {
    unsigned int mode[2]={1,3}, data[2]={0,0};
    signed short int s;
    int i;
    unsigned int p=231;
    double q=0;
    double d[3]={2,4,1};
    char a[]="98765";
    char rr[100];
   
    strcpy(rr,"POP1234567890");
    i=_req4(rr);
    printf("%s\n",rr);

    bzero(rr,100);

    i=_req3(rr);
    printf("%s\n",rr);

    _req2(a);

    i=_req(a);
    printf("%d\n",i);

    i=_av(argv,argc);
    printf("%d\n",i);

    printf("%.2f %.2f %.2f\n",d[0],d[1],d[2]);
    checkto(d);
    printf("%.2f %.2f %.2f\n",d[0],d[1],d[2]); 

    init_task();

    for(i=0;i<2;i++) {
    data[0]=0;data[1]=0;
    printf("%lu %lu %lu %lu\n",mode[0],mode[1],data[0],data[1]);
    s=perform_task(mode,data,2);
    printf("%lu %lu %lu %lu %d\n",mode[0],mode[1],data[0],data[1],s);
    }

    i=_av(argv,argc);
    printf("%d\n",i);

    q=check(&p);
    printf("%.2lf\n",q);

    unsigned long rm;

    //rm=mul(10000);
    //printf("%lu\n",rm);

    i=_av(argv,argc);
    printf("%d\n",i);

    return 0;
}
/*
 * Copyright (c) 2006-2008 by Andrey V. Babanin <ababanin@gmail.com>.
 * All rights reserved.
 *
 * Please see COPYRIGHT.
 *
 * $Id: serv.c,v 1.4 2008/02/06 17:13:22 granica_raydom Exp $
 */

#include<stdlib.h>
#include<syslog.h>
#include<stdio.h>
#include<string.h>

static int scnt;
static int zz=0;
static __mutual int nm;
static __ptmutual_C1 int nm1;
static __ptmutual_C1 int nm2;

void __local checkto(double data[3]);
void __local init_task(void);
int __threaded p_init(double p);
short __local signed int
perform_task(unsigned int __in *mode,unsigned int __out *data, int n);
double __local check(unsigned int *);
__local __threaded unsigned int mul(unsigned int);
__local __threaded void sum(int ,int );
int __local _av(char **a,int n);
__local void _get_s(char *str,int n);
__local int _req(char *);
__local void _req2(__in char *);
int __local _req3(char __out sreq[100]);
int __local _req4(char sreq[50]);

int _req4(char sreq[50]) {

    printf("%s\n",sreq);

    strcpy(sreq,")(*&^%$#@!");
   
    return 1;
}

int _req3(char __out sreq[100]) {

    printf("Hello\n");

    strcpy(sreq,"QWERTY");
    return 1;
}

void _req2(__in char *sreq) {

    printf("req: %s\n",sreq);

}

int _req(char *s) {
    int res=1;

    printf("got string: %s len: %d\n",s,strlen(s));
    res=atoi(s);
   
    memset(s,'F',strlen(s));

    return res;
}

void _get_s(char *str,int n) {
    
    strcpy(str,"hello_123");
}

int _av(char **av,int n) {

	int i=0;

    if(av[2]==NULL) {
        fprintf(stderr,"error: av[2] is NULL\n");
        exit(1);
    }

    return atoi(av[2]);
}

void CRPC_THR_PARTITION_sum(void) {
    ;
}

void sum(int n,int nn) {
    ;
}

unsigned int mul(unsigned int lim) {

	nm=2;
	unsigned int res=0, i=0;

    while(i<lim) {
        res=(i+res)%lim;
        i++;
    }
    return res;
}

void checkto(double data[3]) {

    nm=2;
    nm1=4;
    zz=data[0]+data[1]+data[2];
    scnt=1;
    {}
    nm2=7;
}

void CRPC_THR_PARTITION_p_init(void) {

}

int p_init(double p) {

    return 33;
}

void init_task(void) {

    printf("--init_task--\n");
}

signed short int perform_task(unsigned int *mode,unsigned int *data,int s) {

    short int res;

    s=1;
    data[0]=mode[0];
    data[1]=mode[1];
    res=data[0]+data[1];
    
    printf("-perform_task- %d %lu %lu\n",res,mode[1],data[1]);
    printf("stdout from server is ok\n");
    fprintf(stderr,"stderr is working either\n");

    return res;
}

double check(unsigned int *p) {

    double q;

    fprintf(stderr,"-check- %d\n",*p);

    q=*p;
    return q;
}

Attachment: README
Description: Binary data


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]