mirror of
https://github.com/protobuf-c/protobuf-c.git
synced 2024-12-29 23:42:12 +08:00
hangs waiting for timer..
git-svn-id: https://protobuf-c.googlecode.com/svn/trunk@125 00440858-1255-0410-a3e6-75ea37f81c3a
This commit is contained in:
parent
b4675f4474
commit
d2995318bd
@ -114,6 +114,7 @@ ProtobufCDispatch *protobuf_c_dispatch_new (ProtobufCAllocator *allocator)
|
|||||||
rv->base.changes = ALLOC (sizeof (ProtobufC_FDNotify) * rv->changes_alloced);
|
rv->base.changes = ALLOC (sizeof (ProtobufC_FDNotify) * rv->changes_alloced);
|
||||||
rv->fd_map_size = 16;
|
rv->fd_map_size = 16;
|
||||||
rv->fd_map = ALLOC (sizeof (FDMap) * rv->fd_map_size);
|
rv->fd_map = ALLOC (sizeof (FDMap) * rv->fd_map_size);
|
||||||
|
rv->allocator = allocator;
|
||||||
memset (rv->fd_map, 255, sizeof (FDMap) * rv->fd_map_size);
|
memset (rv->fd_map, 255, sizeof (FDMap) * rv->fd_map_size);
|
||||||
return &rv->base;
|
return &rv->base;
|
||||||
}
|
}
|
||||||
@ -141,7 +142,7 @@ ProtobufCDispatch *protobuf_c_dispatch_default (void)
|
|||||||
{
|
{
|
||||||
static ProtobufCDispatch *def = NULL;
|
static ProtobufCDispatch *def = NULL;
|
||||||
if (def == NULL)
|
if (def == NULL)
|
||||||
def = protobuf_c_dispatch_new (NULL);
|
def = protobuf_c_dispatch_new (&protobuf_c_default_allocator);
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <netdb.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -693,6 +694,21 @@ destroy_client_rpc (ProtobufCService *service)
|
|||||||
client->allocator->free (client->allocator, client);
|
client->allocator->free (client->allocator, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
trivial_sync_libc_resolver (ProtobufCDispatch *dispatch,
|
||||||
|
const char *name,
|
||||||
|
ProtobufC_NameLookup_Found found_func,
|
||||||
|
ProtobufC_NameLookup_Failed failed_func,
|
||||||
|
void *callback_data)
|
||||||
|
{
|
||||||
|
struct hostent *ent;
|
||||||
|
ent = gethostbyname (name);
|
||||||
|
if (ent == NULL)
|
||||||
|
failed_func (hstrerror (h_errno), callback_data);
|
||||||
|
else
|
||||||
|
found_func ((const uint8_t *) ent->h_addr_list[0], callback_data);
|
||||||
|
}
|
||||||
|
|
||||||
ProtobufCService *protobuf_c_rpc_client_new (ProtobufC_RPC_AddressType type,
|
ProtobufCService *protobuf_c_rpc_client_new (ProtobufC_RPC_AddressType type,
|
||||||
const char *name,
|
const char *name,
|
||||||
const ProtobufCServiceDescriptor *descriptor,
|
const ProtobufCServiceDescriptor *descriptor,
|
||||||
@ -712,10 +728,32 @@ ProtobufCService *protobuf_c_rpc_client_new (ProtobufC_RPC_AddressType type,
|
|||||||
rv->name = strcpy (allocator->alloc (allocator, strlen (name) + 1), name);
|
rv->name = strcpy (allocator->alloc (allocator, strlen (name) + 1), name);
|
||||||
rv->state = PROTOBUF_C_CLIENT_STATE_INIT;
|
rv->state = PROTOBUF_C_CLIENT_STATE_INIT;
|
||||||
rv->fd = -1;
|
rv->fd = -1;
|
||||||
|
rv->autoretry = 1;
|
||||||
|
rv->autoretry_millis = 2*1000;
|
||||||
|
rv->resolver = trivial_sync_libc_resolver;
|
||||||
rv->info.init.idle = protobuf_c_dispatch_add_idle (dispatch, handle_init_idle, rv);
|
rv->info.init.idle = protobuf_c_dispatch_add_idle (dispatch, handle_init_idle, rv);
|
||||||
return &rv->base_service;
|
return &rv->base_service;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protobuf_c_boolean
|
||||||
|
protobuf_c_rpc_client_is_connected (ProtobufC_RPC_Client *client)
|
||||||
|
{
|
||||||
|
return client->state == PROTOBUF_C_CLIENT_STATE_CONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
protobuf_c_rpc_client_set_autoretry_period (ProtobufC_RPC_Client *client,
|
||||||
|
unsigned millis)
|
||||||
|
{
|
||||||
|
client->autoretry = 1;
|
||||||
|
client->autoretry_millis = millis;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
protobuf_c_rpc_client_disable_autoretry (ProtobufC_RPC_Client *client)
|
||||||
|
{
|
||||||
|
client->autoretry = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* === Server === */
|
/* === Server === */
|
||||||
typedef struct _ServerRequest ServerRequest;
|
typedef struct _ServerRequest ServerRequest;
|
||||||
typedef struct _ServerConnection ServerConnection;
|
typedef struct _ServerConnection ServerConnection;
|
||||||
@ -1163,3 +1201,23 @@ protobuf_c_rpc_server_new (ProtobufC_RPC_AddressType type,
|
|||||||
}
|
}
|
||||||
return server_new_from_fd (fd, name, service, dispatch);
|
return server_new_from_fd (fd, name, service, dispatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProtobufCService *
|
||||||
|
protobuf_c_rpc_server_destroy (ProtobufC_RPC_Server *server,
|
||||||
|
protobuf_c_boolean destroy_underlying)
|
||||||
|
{
|
||||||
|
ProtobufCService *rv = destroy_underlying ? NULL : server->underlying;
|
||||||
|
while (server->first_connection != NULL)
|
||||||
|
server_connection_close (server->first_connection);
|
||||||
|
server->allocator->free (server->allocator, server->bind_name);
|
||||||
|
while (server->recycled_requests != NULL)
|
||||||
|
{
|
||||||
|
ServerRequest *req = server->recycled_requests;
|
||||||
|
server->recycled_requests = req->info.recycled.next;
|
||||||
|
server->allocator->free (server->allocator, req);
|
||||||
|
}
|
||||||
|
if (destroy_underlying)
|
||||||
|
protobuf_c_service_destroy (server->underlying);
|
||||||
|
server->allocator->free (server->allocator, server);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
@ -78,6 +78,9 @@ void protobuf_c_rpc_client_disable_autoretry (ProtobufC_RPC_Client *client);
|
|||||||
void protobuf_c_rpc_client_set_autoretry_period (ProtobufC_RPC_Client *client,
|
void protobuf_c_rpc_client_set_autoretry_period (ProtobufC_RPC_Client *client,
|
||||||
unsigned millis);
|
unsigned millis);
|
||||||
|
|
||||||
|
/* checking the state of the client */
|
||||||
|
protobuf_c_boolean protobuf_c_rpc_client_is_connected (ProtobufC_RPC_Client *client);
|
||||||
|
|
||||||
/* NOTE: we don't actually start connecting til the main-loop runs,
|
/* NOTE: we don't actually start connecting til the main-loop runs,
|
||||||
so you may configure the client immediately after creation */
|
so you may configure the client immediately after creation */
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ test__by_name (Foo__DirLookup_Service *service,
|
|||||||
person.n_phone = 1;
|
person.n_phone = 1;
|
||||||
person.phone = pns;
|
person.phone = pns;
|
||||||
person.email = email;
|
person.email = email;
|
||||||
|
person.name = name->name;
|
||||||
result.person = &person;
|
result.person = &person;
|
||||||
}
|
}
|
||||||
closure (&result, closure_data);
|
closure (&result, closure_data);
|
||||||
@ -82,6 +83,14 @@ test_not_found_closure (const Foo__LookupResult *result,
|
|||||||
* (protobuf_c_boolean *) closure_data = 1;
|
* (protobuf_c_boolean *) closure_data = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_defunct_closure (const Foo__LookupResult *result,
|
||||||
|
void *closure_data)
|
||||||
|
{
|
||||||
|
assert (result == NULL);
|
||||||
|
* (protobuf_c_boolean *) closure_data = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_service (ProtobufCService *service)
|
test_service (ProtobufCService *service)
|
||||||
@ -93,28 +102,61 @@ test_service (ProtobufCService *service)
|
|||||||
is_done = 0;
|
is_done = 0;
|
||||||
foo__dir_lookup__by_name (service, &name, test_dave_closure, &is_done);
|
foo__dir_lookup__by_name (service, &name, test_dave_closure, &is_done);
|
||||||
while (!is_done)
|
while (!is_done)
|
||||||
protobuf_c_dispatch_run_once (protobuf_c_dispatch_default ());
|
protobuf_c_dispatch_run (protobuf_c_dispatch_default ());
|
||||||
|
|
||||||
name.name = "joe the plumber";
|
name.name = "joe the plumber";
|
||||||
is_done = 0;
|
is_done = 0;
|
||||||
foo__dir_lookup__by_name (service, &name, test_joe_the_plumber_closure, &is_done);
|
foo__dir_lookup__by_name (service, &name, test_joe_the_plumber_closure, &is_done);
|
||||||
while (!is_done)
|
while (!is_done)
|
||||||
protobuf_c_dispatch_run_once (protobuf_c_dispatch_default ());
|
protobuf_c_dispatch_run (protobuf_c_dispatch_default ());
|
||||||
|
|
||||||
name.name = "asdfvcvzxsa";
|
name.name = "asdfvcvzxsa";
|
||||||
is_done = 0;
|
is_done = 0;
|
||||||
foo__dir_lookup__by_name (service, &name, test_not_found_closure, &is_done);
|
foo__dir_lookup__by_name (service, &name, test_not_found_closure, &is_done);
|
||||||
while (!is_done)
|
while (!is_done)
|
||||||
protobuf_c_dispatch_run_once (protobuf_c_dispatch_default ());
|
protobuf_c_dispatch_run (protobuf_c_dispatch_default ());
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
test_defunct_client (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_defunct_closure, &is_done);
|
||||||
|
while (!is_done)
|
||||||
|
protobuf_c_dispatch_run (protobuf_c_dispatch_default ());
|
||||||
|
|
||||||
|
name.name = "joe the plumber";
|
||||||
|
is_done = 0;
|
||||||
|
foo__dir_lookup__by_name (service, &name, test_defunct_closure, &is_done);
|
||||||
|
while (!is_done)
|
||||||
|
protobuf_c_dispatch_run (protobuf_c_dispatch_default ());
|
||||||
|
|
||||||
|
name.name = "asdfvcvzxsa";
|
||||||
|
is_done = 0;
|
||||||
|
foo__dir_lookup__by_name (service, &name, test_defunct_closure, &is_done);
|
||||||
|
while (!is_done)
|
||||||
|
protobuf_c_dispatch_run (protobuf_c_dispatch_default ());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- main() --- */
|
/* --- main() --- */
|
||||||
|
static void
|
||||||
|
set_boolean_true (ProtobufCDispatch *dispatch,
|
||||||
|
void *func_data)
|
||||||
|
{
|
||||||
|
(void) dispatch;
|
||||||
|
* (protobuf_c_boolean *) func_data = 1;
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
protobuf_c_boolean is_done;
|
protobuf_c_boolean is_done;
|
||||||
ProtobufCService *local_service = (ProtobufCService *) &the_dir_lookup_service;
|
ProtobufCService *local_service = (ProtobufCService *) &the_dir_lookup_service;
|
||||||
ProtobufCService *remote_service;
|
ProtobufCService *remote_service;
|
||||||
ProtobufC_RPC_Client *client;
|
ProtobufC_RPC_Client *client;
|
||||||
|
ProtobufC_RPC_Server *server;
|
||||||
|
|
||||||
test_service (local_service);
|
test_service (local_service);
|
||||||
|
|
||||||
@ -132,7 +174,7 @@ int main()
|
|||||||
250, set_boolean_true, &is_done);
|
250, set_boolean_true, &is_done);
|
||||||
while (!is_done)
|
while (!is_done)
|
||||||
{
|
{
|
||||||
protobuf_c_dispatch_run_once (protobuf_c_dispatch_default ());
|
protobuf_c_dispatch_run (protobuf_c_dispatch_default ());
|
||||||
assert (!protobuf_c_rpc_client_is_connected (client));
|
assert (!protobuf_c_rpc_client_is_connected (client));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +188,7 @@ int main()
|
|||||||
protobuf_c_dispatch_add_timer_millis (protobuf_c_dispatch_default (),
|
protobuf_c_dispatch_add_timer_millis (protobuf_c_dispatch_default (),
|
||||||
250, set_boolean_true, &is_done);
|
250, set_boolean_true, &is_done);
|
||||||
while (!is_done && !protobuf_c_rpc_client_is_connected (client))
|
while (!is_done && !protobuf_c_rpc_client_is_connected (client))
|
||||||
protobuf_c_dispatch_run_once (protobuf_c_dispatch_default ());
|
protobuf_c_dispatch_run (protobuf_c_dispatch_default ());
|
||||||
|
|
||||||
/* technically, there's no way to know how long it'll take to connect
|
/* technically, there's no way to know how long it'll take to connect
|
||||||
if the machine is heavily loaded, so the following
|
if the machine is heavily loaded, so the following
|
||||||
@ -156,17 +198,31 @@ int main()
|
|||||||
|
|
||||||
/* wait for the timer to elapse, since that's laziest way to handle it. */
|
/* wait for the timer to elapse, since that's laziest way to handle it. */
|
||||||
while (!is_done)
|
while (!is_done)
|
||||||
protobuf_c_dispatch_run_once (protobuf_c_dispatch_default ());
|
protobuf_c_dispatch_run (protobuf_c_dispatch_default ());
|
||||||
|
|
||||||
/* Test the client */
|
/* Test the client */
|
||||||
test_service (remote_service);
|
test_service (remote_service);
|
||||||
|
|
||||||
/* Destroy the server and ensure that a request is failed in
|
/* Destroy the server and ensure that a request is failed in
|
||||||
a timely fashion. */
|
a timely fashion. */
|
||||||
...
|
protobuf_c_rpc_server_destroy (server, 0);
|
||||||
|
server = NULL;
|
||||||
|
test_defunct_client (remote_service);
|
||||||
|
|
||||||
/* Create a server again and wait for the client to reconnect. */
|
/* Create a server again and wait for the client to reconnect. */
|
||||||
...
|
server = protobuf_c_rpc_server_new (PROTOBUF_C_RPC_ADDRESS_LOCAL,
|
||||||
|
"test.socket",
|
||||||
|
local_service,
|
||||||
|
NULL);
|
||||||
|
assert (server != NULL);
|
||||||
|
is_done = 0;
|
||||||
|
while (!is_done)
|
||||||
|
protobuf_c_dispatch_run (protobuf_c_dispatch_default ());
|
||||||
|
protobuf_c_dispatch_add_timer_millis (protobuf_c_dispatch_default (),
|
||||||
|
250, set_boolean_true, &is_done);
|
||||||
|
while (!is_done)
|
||||||
|
protobuf_c_dispatch_run (protobuf_c_dispatch_default ());
|
||||||
|
assert (protobuf_c_rpc_client_is_connected (client));
|
||||||
|
|
||||||
/* Test the client again, for kicks. */
|
/* Test the client again, for kicks. */
|
||||||
test_service (remote_service);
|
test_service (remote_service);
|
||||||
@ -175,7 +231,7 @@ int main()
|
|||||||
protobuf_c_service_destroy (remote_service);
|
protobuf_c_service_destroy (remote_service);
|
||||||
|
|
||||||
/* Destroy the server */
|
/* Destroy the server */
|
||||||
protobuf_c_rpc_server_destroy (server);
|
protobuf_c_rpc_server_destroy (server, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user