mirror of
https://github.com/protobuf-c/protobuf-c.git
synced 2024-12-28 14:48:18 +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->fd_map_size = 16;
|
||||
rv->fd_map = ALLOC (sizeof (FDMap) * rv->fd_map_size);
|
||||
rv->allocator = allocator;
|
||||
memset (rv->fd_map, 255, sizeof (FDMap) * rv->fd_map_size);
|
||||
return &rv->base;
|
||||
}
|
||||
@ -141,7 +142,7 @@ ProtobufCDispatch *protobuf_c_dispatch_default (void)
|
||||
{
|
||||
static ProtobufCDispatch *def = NULL;
|
||||
if (def == NULL)
|
||||
def = protobuf_c_dispatch_new (NULL);
|
||||
def = protobuf_c_dispatch_new (&protobuf_c_default_allocator);
|
||||
return def;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
@ -693,6 +694,21 @@ destroy_client_rpc (ProtobufCService *service)
|
||||
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,
|
||||
const char *name,
|
||||
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->state = PROTOBUF_C_CLIENT_STATE_INIT;
|
||||
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);
|
||||
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 === */
|
||||
typedef struct _ServerRequest ServerRequest;
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
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,
|
||||
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.phone = pns;
|
||||
person.email = email;
|
||||
person.name = name->name;
|
||||
result.person = &person;
|
||||
}
|
||||
closure (&result, closure_data);
|
||||
@ -82,6 +83,14 @@ test_not_found_closure (const Foo__LookupResult *result,
|
||||
* (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
|
||||
test_service (ProtobufCService *service)
|
||||
@ -93,28 +102,61 @@ test_service (ProtobufCService *service)
|
||||
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 ());
|
||||
protobuf_c_dispatch_run (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 ());
|
||||
protobuf_c_dispatch_run (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 ());
|
||||
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() --- */
|
||||
static void
|
||||
set_boolean_true (ProtobufCDispatch *dispatch,
|
||||
void *func_data)
|
||||
{
|
||||
(void) dispatch;
|
||||
* (protobuf_c_boolean *) func_data = 1;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
protobuf_c_boolean is_done;
|
||||
ProtobufCService *local_service = (ProtobufCService *) &the_dir_lookup_service;
|
||||
ProtobufCService *remote_service;
|
||||
ProtobufC_RPC_Client *client;
|
||||
ProtobufC_RPC_Server *server;
|
||||
|
||||
test_service (local_service);
|
||||
|
||||
@ -132,7 +174,7 @@ int main()
|
||||
250, set_boolean_true, &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));
|
||||
}
|
||||
|
||||
@ -146,7 +188,7 @@ int main()
|
||||
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 ());
|
||||
protobuf_c_dispatch_run (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
|
||||
@ -156,17 +198,31 @@ int main()
|
||||
|
||||
/* 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 ());
|
||||
protobuf_c_dispatch_run (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. */
|
||||
...
|
||||
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. */
|
||||
...
|
||||
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_service (remote_service);
|
||||
@ -175,7 +231,7 @@ int main()
|
||||
protobuf_c_service_destroy (remote_service);
|
||||
|
||||
/* Destroy the server */
|
||||
protobuf_c_rpc_server_destroy (server);
|
||||
protobuf_c_rpc_server_destroy (server, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user