Commit b4675f44 authored by lahiker42's avatar lahiker42

rpc work.


git-svn-id: https://protobuf-c.googlecode.com/svn/trunk@124 00440858-1255-0410-a3e6-75ea37f81c3a
parent 70d37e82
......@@ -64,3 +64,9 @@ protobuf_c_service_generated_init (ProtobufCService *service,
const ProtobufCServiceDescriptor *descriptor,
ProtobufCServiceDestroy destroy);
void
protobuf_c_service_invoke_internal(ProtobufCService *service,
unsigned method_index,
const ProtobufCMessage *input,
ProtobufCClosure closure,
void *closure_data);
......@@ -1606,8 +1606,8 @@ typedef void (*GenericHandler)(void *service,
const ProtobufCMessage *input,
ProtobufCClosure closure,
void *closure_data);
static void
service_machgen_invoke(ProtobufCService *service,
void
protobuf_c_service_invoke_internal(ProtobufCService *service,
unsigned method_index,
const ProtobufCMessage *input,
ProtobufCClosure closure,
......@@ -1629,7 +1629,7 @@ protobuf_c_service_generated_init (ProtobufCService *service,
ASSERT_IS_SERVICE_DESCRIPTOR(descriptor);
service->descriptor = descriptor;
service->destroy = destroy;
service->invoke = service_machgen_invoke;
service->invoke = protobuf_c_service_invoke_internal;
memset (service + 1, 0, descriptor->n_methods * sizeof (GenericHandler));
}
......
......@@ -36,6 +36,7 @@ ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor,
vars_["fullname"] = descriptor_->full_name();
vars_["cname"] = FullNameToC(descriptor_->full_name());
vars_["lcfullname"] = FullNameToLower(descriptor_->full_name());
vars_["ucfullname"] = FullNameToUpper(descriptor_->full_name());
vars_["lcfullpadd"] = ConvertToSpaces(vars_["lcfullname"]);
vars_["package"] = descriptor_->file()->package();
if (dllexport_decl.empty()) {
......@@ -51,6 +52,7 @@ ServiceGenerator::~ServiceGenerator() {}
void ServiceGenerator::GenerateMainHFile(io::Printer* printer)
{
GenerateVfuncs(printer);
GenerateInitMacros(printer);
GenerateCreateServiceDeclaration(printer);
GenerateCallersDeclarations(printer);
}
......@@ -81,6 +83,24 @@ void ServiceGenerator::GenerateVfuncs(io::Printer* printer)
"void $lcfullname$__init ($cname$_Service *service,\n"
" $lcfullpadd$ $cname$_ServiceDestroy destroy);\n");
}
void ServiceGenerator::GenerateInitMacros(io::Printer* printer)
{
printer->Print(vars_,
"#define $ucfullname$__BASE_INIT \\\n"
" { &$lcfullname$__descriptor, protobuf_c_service_invoke_internal, NULL }\n"
"#define $ucfullname$__INIT(function_prefix__) \\\n"
" { $ucfullname$__BASE_INIT");
for (int i = 0; i < descriptor_->method_count(); i++) {
const MethodDescriptor *method = descriptor_->method(i);
string lcname = CamelToLower(method->name());
vars_["method"] = lcname;
vars_["metpad"] = ConvertToSpaces(lcname);
printer->Print(vars_,
",\\\n function_prefix__ ## $method$");
}
printer->Print(vars_,
" }\n");
}
void ServiceGenerator::GenerateCallersDeclarations(io::Printer* printer)
{
for (int i = 0; i < descriptor_->method_count(); i++) {
......
......@@ -48,6 +48,7 @@ class ServiceGenerator {
// Header stuff.
void GenerateMainHFile(io::Printer* printer);
void GenerateVfuncs(io::Printer* printer);
void GenerateInitMacros(io::Printer* printer);
void GenerateCreateServiceDeclaration(io::Printer* printer);
void GenerateDescriptorDeclarations(io::Printer* printer);
void GenerateCallersDeclarations(io::Printer* printer);
......
check_PROGRAMS = test-generated-code test-generated-code2
check_PROGRAMS = test-generated-code test-generated-code2 test-rpc
noinst_PROGRAMS = cxx-generate-packed-data
INCLUDES = -I$(srcdir)/..
test_generated_code_SOURCES = \
......@@ -11,6 +11,11 @@ test-generated-code2.c \
generated-code/test-full.pb-c.c
test_generated_code2_LDADD = \
../libprotobuf-c.la
test_rpc_SOURCES = \
test-rpc.c \
generated-code/test.pb-c.c
test_rpc_LDADD = \
../libprotobuf-c.la
cxx_generate_packed_data_SOURCES = \
cxx-generate-packed-data.cc generated-code/test-full.pb.cc
cxx_generate_packed_data_LDADD = -lprotobuf
......
#include <assert.h>
#include <string.h>
#include "generated-code/test.pb-c.h"
#include <google/protobuf-c/protobuf-c-rpc.h>
/* --- A local service --- */
static void
test__by_name (Foo__DirLookup_Service *service,
const Foo__Name *name,
Foo__LookupResult_Closure closure,
void *closure_data)
{
Foo__LookupResult result = FOO__LOOKUP_RESULT__INIT;
Foo__Person__PhoneNumber pn = FOO__PERSON__PHONE_NUMBER__INIT;
Foo__Person__PhoneNumber *pns[] = { &pn };
Foo__Person person = FOO__PERSON__INIT;
char *number = NULL;
Foo__Person__PhoneType type = FOO__PERSON__PHONE_TYPE__MOBILE;
char *email = NULL;
(void) service;
if (name->name == NULL)
closure (NULL, closure_data);
else if (strcmp (name->name, "dave") == 0)
{
number = "555-1212";
type = FOO__PERSON__PHONE_TYPE__MOBILE;
}
else if (strcmp (name->name, "joe the plumber") == 0)
{
number = "976-PIPE";
type = FOO__PERSON__PHONE_TYPE__WORK;
email = "joe@the-plumber.com";
}
if (number != NULL)
{
pn.number = number;
pn.type = type;
person.n_phone = 1;
person.phone = pns;
person.email = email;
result.person = &person;
}
closure (&result, closure_data);
}
static Foo__DirLookup_Service the_dir_lookup_service =
FOO__DIR_LOOKUP__INIT(test__);
static void
test_dave_closure (const Foo__LookupResult *result,
void *closure_data)
{
assert (result);
assert (result->person != NULL);
assert (result->person->name != NULL);
assert (strcmp (result->person->name, "dave") == 0);
assert (result->person->n_phone == 1);
assert (strcmp (result->person->phone[0]->number, "555-1212") == 0);
assert (result->person->phone[0]->type == FOO__PERSON__PHONE_TYPE__MOBILE);
* (protobuf_c_boolean *) closure_data = 1;
}
static void
test_joe_the_plumber_closure (const Foo__LookupResult *result,
void *closure_data)
{
assert (result);
assert (result->person != NULL);
assert (result->person->name != NULL);
assert (strcmp (result->person->name, "joe the plumber") == 0);
assert (result->person->n_phone == 1);
assert (strcmp (result->person->phone[0]->number, "976-PIPE") == 0);
assert (result->person->phone[0]->type == FOO__PERSON__PHONE_TYPE__WORK);
* (protobuf_c_boolean *) closure_data = 1;
}
static void
test_not_found_closure (const Foo__LookupResult *result,
void *closure_data)
{
assert (result);
assert (result->person == NULL);
* (protobuf_c_boolean *) closure_data = 1;
}
static void
test_service (ProtobufCService *service)
{
Foo__Name name = FOO__NAME__INIT;
protobuf_c_boolean is_done;
name.name = "dave";
is_done = 0;
foo__dir_lookup__by_name (service, &name, test_dave_closure, &is_done);
while (!is_done)
protobuf_c_dispatch_run_once (protobuf_c_dispatch_default ());
name.name = "joe the plumber";
is_done = 0;
foo__dir_lookup__by_name (service, &name, test_joe_the_plumber_closure, &is_done);
while (!is_done)
protobuf_c_dispatch_run_once (protobuf_c_dispatch_default ());
name.name = "asdfvcvzxsa";
is_done = 0;
foo__dir_lookup__by_name (service, &name, test_not_found_closure, &is_done);
while (!is_done)
protobuf_c_dispatch_run_once (protobuf_c_dispatch_default ());
}
/* --- main() --- */
int main()
{
protobuf_c_boolean is_done;
ProtobufCService *local_service = (ProtobufCService *) &the_dir_lookup_service;
ProtobufCService *remote_service;
ProtobufC_RPC_Client *client;
test_service (local_service);
/* Create a client with no server. Verify that
the client returns a failure immediately */
remote_service = protobuf_c_rpc_client_new (PROTOBUF_C_RPC_ADDRESS_LOCAL,
"test.socket",
&foo__dir_lookup__descriptor,
NULL);
assert (remote_service != NULL);
client = (ProtobufC_RPC_Client *) remote_service;
protobuf_c_rpc_client_set_autoretry_period (client, 10);
is_done = 0;
protobuf_c_dispatch_add_timer_millis (protobuf_c_dispatch_default (),
250, set_boolean_true, &is_done);
while (!is_done)
{
protobuf_c_dispatch_run_once (protobuf_c_dispatch_default ());
assert (!protobuf_c_rpc_client_is_connected (client));
}
/* Create a server and wait for the client to connect. */
server = protobuf_c_rpc_server_new (PROTOBUF_C_RPC_ADDRESS_LOCAL,
"test.socket",
local_service,
NULL);
assert (server != NULL);
is_done = 0;
protobuf_c_dispatch_add_timer_millis (protobuf_c_dispatch_default (),
250, set_boolean_true, &is_done);
while (!is_done && !protobuf_c_rpc_client_is_connected (client))
protobuf_c_dispatch_run_once (protobuf_c_dispatch_default ());
/* technically, there's no way to know how long it'll take to connect
if the machine is heavily loaded, so the following
assert could fail, without it meaning an error. On an unloaded system,
it really shouldn't happen. */
assert (protobuf_c_rpc_client_is_connected (client));
/* wait for the timer to elapse, since that's laziest way to handle it. */
while (!is_done)
protobuf_c_dispatch_run_once (protobuf_c_dispatch_default ());
/* Test the client */
test_service (remote_service);
/* Destroy the server and ensure that a request is failed in
a timely fashion. */
...
/* Create a server again and wait for the client to reconnect. */
...
/* Test the client again, for kicks. */
test_service (remote_service);
/* Destroy the client */
protobuf_c_service_destroy (remote_service);
/* Destroy the server */
protobuf_c_rpc_server_destroy (server);
return 0;
}
......@@ -19,10 +19,15 @@ message Person {
repeated PhoneNumber phone = 4;
}
message LookupResult
{
optional Person person = 1;
}
message Name {
optional string name = 1;
};
service DirLookup {
rpc ByName (Name) returns (Person);
rpc ByName (Name) returns (LookupResult);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment