2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-03 16:15:27 +00:00

checkpoint

This commit is contained in:
David Lawrence
2000-01-13 06:13:26 +00:00
parent 43236eb0e1
commit 6cdff83aae
10 changed files with 305 additions and 324 deletions

View File

@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: connection.c,v 1.6 2000/01/11 01:49:22 tale Exp $ */
/* $Id: connection.c,v 1.7 2000/01/13 06:13:21 tale Exp $ */
/* Principal Author: Ted Lemon */
@@ -35,12 +35,6 @@
#include <omapi/private.h>
/*
* Forward declarations.
*/
void
connection_send(omapi_connection_object_t *connection);
/*
* Swiped from bin/tests/sdig.c.
*/
@@ -144,6 +138,12 @@ connect_done(isc_task_t *task, isc_event_t *event) {
connection->events_pending--;
/*
* XXXDCL For some reason, a "connection refused" error is not
* being indicated here when it would be expected. I wonder
* how that error is indicated.
*/
if (connectevent->result != ISC_R_SUCCESS) {
abandon_connection(connection, event, connectevent->result);
return;
@@ -180,6 +180,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
isc_socket_t *socket;
isc_socketevent_t *socketevent;
omapi_connection_object_t *connection;
unsigned int original_bytes_needed;
socket = event->sender;
socketevent = (isc_socketevent_t *)event;
@@ -204,21 +205,21 @@ recv_done(isc_task_t *task, isc_event_t *event) {
connection->in_bytes += socketevent->n;
original_bytes_needed = connection->bytes_needed;
while (connection->bytes_needed <= connection->in_bytes &&
connection->bytes_needed > 0)
omapi_signal(event->arg, "ready", connection);
omapi_signal((omapi_object_t *)connection, "ready",
connection);
#if 0
/*
* XXXDCL it may be the case that another recv task should be queued,
* but I haven't thought it through fully.
* Queue up another recv request. If the bufferlist is empty,
* then, something under omapi_signal already called
* omapi_connection_require and queued the recv (which is
* what emptied the bufferlist).
*/
if (connection->bytes_needed > 0)
isc_socket_recvv(socket, &connection->input_buffers,
connection->bytes_needed -
connection->in_bytes,
task, recv_done, connection);
#endif
if (! ISC_LIST_EMPTY(connection->input_buffers))
omapi_connection_require((omapi_object_t *)connection, 0);
isc_event_free(&event);
@@ -311,6 +312,7 @@ omapi_connection_toserver(omapi_object_t *protocol, const char *server_name,
if (result != ISC_R_SUCCESS)
return (result);
/* XXXDCL Make cleanup better */
/*
* Prepare the task that will wait for the connection to be made.
*/
@@ -345,6 +347,8 @@ omapi_connection_toserver(omapi_object_t *protocol, const char *server_name,
return (result);
}
connection->is_client = ISC_TRUE;
connection->task = task;
ISC_LIST_INIT(connection->input_buffers);
@@ -352,6 +356,23 @@ omapi_connection_toserver(omapi_object_t *protocol, const char *server_name,
ISC_LIST_INIT(connection->output_buffers);
ISC_LIST_APPEND(connection->output_buffers, obuffer, link);
result = isc_mutex_init(&connection->mutex);
if (result != ISC_R_SUCCESS)
return (result);
result = isc_condition_init(&connection->waiter);
if (result != ISC_R_SUCCESS)
return (result);
/*
* An introductory message is expected from the server.
* It is not necessary to lock the mutex here because there
* will be no recv() tasks that could possibly compete for the
* messages_expected variable, since isc_socket_create has
* not even been called yet.
*/
connection->messages_expected = 1;
/*
* Tie the new connection object to the protocol object.
*/
@@ -395,6 +416,8 @@ omapi_connection_toserver(omapi_object_t *protocol, const char *server_name,
return (result);
}
connection->events_pending++;
return (result);
}
@@ -481,6 +504,8 @@ omapi_connection_copyout(unsigned char *dst, omapi_object_t *generic,
if (size > connection->in_bytes)
return (ISC_R_NOMORE);
connection->bytes_needed -= size;
buffer = ISC_LIST_HEAD(connection->input_buffers);
/*
@@ -492,7 +517,13 @@ omapi_connection_copyout(unsigned char *dst, omapi_object_t *generic,
if (copy_bytes > size)
copy_bytes = size;
(void)memcpy(dst, buffer->base + buffer->current, copy_bytes);
/*
* When dst == NULL, this function is being used to skip
* over uninteresting input.
*/
if (dst != NULL)
(void)memcpy(dst, buffer->base + buffer->current,
copy_bytes);
isc_buffer_forward(buffer, copy_bytes);
@@ -639,21 +670,77 @@ omapi_connection_require(omapi_object_t *generic, unsigned int bytes) {
/*
* Queue the receive task.
* XXXDCL The "minimum" argument has not been fully thought out.
* It will *probably* work fine in a lockstep protocol, but I
* am not so sure what will happen when
*/
isc_socket_recvv(connection->socket, &connection->input_buffers,
connection->bytes_needed - connection->in_bytes,
connection->task, recv_done, connection);
connection->events_pending++;
return (OMAPI_R_NOTYET);
}
/*
* This function is meant to pause the client until it has received
* a message from the server, either the introductory message or a response
* to a message it has sent. Because the socket library is multithreaded,
* those events can happen before omapi_connection_wait is ever called.
* So a counter needs to be set for every expected message, and this
* function can only return when that counter is 0.
*/
isc_result_t
omapi_connection_wait(omapi_object_t *object,
omapi_object_t *connection_handle,
isc_time_t *timeout)
{
/*
* 'object' is not really used.
*/
omapi_connection_object_t *connection;
isc_result_t result, wait_result;
REQUIRE(object != NULL && connection_handle != NULL);
REQUIRE(connection_handle->type == omapi_type_connection);
connection = (omapi_connection_object_t *)connection_handle;
/*
* This routine is not valid for server connections.
*/
REQUIRE(connection->is_client);
result = isc_mutex_lock(&connection->mutex);
if (result != ISC_R_SUCCESS)
return (result);
wait_result = ISC_R_SUCCESS;
while (connection->messages_expected > 0 &&
wait_result == ISC_R_SUCCESS) {
if (timeout == NULL)
wait_result = isc_condition_wait(&connection->waiter,
&connection->mutex);
else
wait_result =
isc_condition_waituntil(&connection->waiter,
&connection->mutex,
timeout);
}
if (wait_result == ISC_R_SUCCESS || wait_result == ISC_R_TIMEDOUT) {
result = isc_mutex_unlock(&connection->mutex);
if (result != ISC_R_SUCCESS)
return (result);
}
return (wait_result);
}
isc_result_t
omapi_connection_setvalue(omapi_object_t *connection, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value)
{
REQUIRE(connection != NULL && connection->type == omapi_type_connection);
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
PASS_SETVALUE(connection);
}
@@ -662,7 +749,8 @@ isc_result_t
omapi_connection_getvalue(omapi_object_t *connection, omapi_object_t *id,
omapi_data_string_t *name, omapi_value_t **value)
{
REQUIRE(connection != NULL && connection->type == omapi_type_connection);
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
PASS_GETVALUE(connection);
}
@@ -673,24 +761,20 @@ omapi_connection_destroy(omapi_object_t *handle, const char *name) {
REQUIRE(handle != NULL && handle->type == omapi_type_connection);
(void)name;
connection = (omapi_connection_object_t *)handle;
if (connection->state == omapi_connection_connected)
omapi_connection_disconnect(handle, OMAPI_FORCE_DISCONNECT);
/*
* XXXDCL why is the listener object is being referenced?
* does it need to be in the connection structure at all?
*/
if (connection->listener != NULL)
OBJECT_DEREF(&connection->listener, name);
}
isc_result_t
omapi_connection_signalhandler(omapi_object_t *connection, const char *name,
va_list ap)
{
REQUIRE(connection != NULL && connection->type == omapi_type_connection);
REQUIRE(connection != NULL &&
connection->type == omapi_type_connection);
PASS_SIGNAL(connection);
}

View File

@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: data.c,v 1.1 2000/01/04 20:04:37 tale Exp $ */
/* $Id: data.c,v 1.2 2000/01/13 06:13:21 tale Exp $ */
/* Principal Author: Ted Lemon */
@@ -108,7 +108,7 @@ omapi_data_reference(omapi_typed_data_t **r, omapi_typed_data_t *h,
const char *name)
{
REQUIRE(r != NULL && h != NULL);
REQUIRE(*r != NULL);
REQUIRE(*r == NULL);
(void)name; /* Unused. */
@@ -118,22 +118,40 @@ omapi_data_reference(omapi_typed_data_t **r, omapi_typed_data_t *h,
void
omapi_data_dereference(omapi_typed_data_t **h, const char *name) {
int length = 0;
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
if (--((*h)->refcnt) <= 0) {
switch ((*h)->type) {
case omapi_datatype_int:
length = OMAPI_TYPED_DATA_INT_LEN;
break;
case omapi_datatype_string:
length = OMAPI_TYPED_DATA_NOBUFFER_LEN +
(*h)->u.buffer.len;
break;
case omapi_datatype_data:
default:
length = OMAPI_TYPED_DATA_NOBUFFER_LEN +
(*h)->u.buffer.len;
break;
case omapi_datatype_object:
OBJECT_DEREF(&(*h)->u.object, name);
length = OMAPI_TYPED_DATA_OBJECT_LEN;
break;
default:
FATAL_ERROR(__FILE__, __LINE__,
"unknown datatype in "
"omapi_data_dereference: %d\n",
(*h)->type);
/* NOTREACHED */
return;
}
isc_mem_put(omapi_mctx, *h, sizeof(*h));
isc_mem_put(omapi_mctx, *h, length);
}
*h = NULL;
}
@@ -144,7 +162,7 @@ omapi_data_newstring(omapi_data_string_t **d, unsigned int len,
omapi_data_string_t *new;
new = isc_mem_get(omapi_mctx, OMAPI_DATA_STRING_EMPTY_SIZE + len);
if (new != NULL)
if (new == NULL)
return (ISC_R_NOMEMORY);
memset(new, 0, OMAPI_DATA_STRING_EMPTY_SIZE);
new->len = len;
@@ -186,7 +204,7 @@ omapi_data_newvalue(omapi_value_t **d, const char *name) {
omapi_value_t *new;
new = isc_mem_get(omapi_mctx, sizeof(*new));
if (new != NULL)
if (new == NULL)
return (ISC_R_NOMEMORY);
memset(new, 0, sizeof *new);

View File

@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: dispatch.c,v 1.6 2000/01/11 01:49:23 tale Exp $ */
/* $Id: dispatch.c,v 1.7 2000/01/13 06:13:22 tale Exp $ */
/* Principal Author: Ted Lemon */
@@ -30,25 +30,6 @@
#include <omapi/private.h>
typedef struct omapi_io_object {
OMAPI_OBJECT_PREAMBLE;
struct omapi_io_object * next;
int (*readfd) (omapi_object_t *);
int (*writefd)(omapi_object_t *);
isc_result_t (*reader) (omapi_object_t *);
isc_result_t (*writer) (omapi_object_t *);
isc_result_t (*reaper) (omapi_object_t *);
} omapi_io_object_t;
typedef struct omapi_waiter_object {
OMAPI_OBJECT_PREAMBLE;
struct omapi_waiter_object * next;
int ready;
} omapi_waiter_object_t;
static omapi_io_object_t omapi_io_states;
isc_uint32_t cur_time;
isc_result_t
omapi_dispatch(struct timeval *t) {
/*
@@ -59,220 +40,6 @@ omapi_dispatch(struct timeval *t) {
return (ISC_R_SUCCESS);
}
isc_result_t
omapi_wait_for_completion(omapi_object_t *object, struct timeval *t) {
isc_result_t result;
omapi_waiter_object_t *waiter = NULL;
omapi_object_t *inner;
if (object != NULL) {
result = omapi_object_new((omapi_object_t **)&waiter,
omapi_type_waiter, sizeof(*waiter));
if (result != ISC_R_SUCCESS)
return (result);
/*
* Paste the waiter object onto the inner object we're
* waiting on.
*/
for (inner = object; inner->inner != NULL;
inner = inner->inner)
;
OBJECT_REF(&waiter->outer, inner, "omapi_wait_for_completion");
OBJECT_REF(&inner->inner, waiter, "omapi_wait_for_completion");
} else
waiter = NULL;
do {
result = omapi_one_dispatch((omapi_object_t *)waiter, t);
if (result != ISC_R_SUCCESS)
return (result);
} while (waiter == NULL || waiter->ready == 0);
if (waiter->outer != NULL) {
if (waiter->outer->inner != NULL) {
OBJECT_DEREF(&waiter->outer->inner,
"omapi_wait_for_completion");
if (waiter->inner != NULL)
OBJECT_REF(&waiter->outer->inner, waiter->inner,
"omapi_wait_for_completion");
}
OBJECT_DEREF(&waiter->outer, "omapi_wait_for_completion");
}
if (waiter->inner != NULL)
OBJECT_DEREF(&waiter->inner, "omapi_wait_for_completion");
OBJECT_DEREF(&waiter, "omapi_wait_for_completion");
return (ISC_R_SUCCESS);
}
isc_result_t
omapi_one_dispatch(omapi_object_t *wo, struct timeval *t) {
fd_set r, w, x;
int count;
int desc;
int max = 0;
struct timeval now, to;
omapi_io_object_t *io, *prev;
isc_result_t result;
omapi_waiter_object_t *waiter;
if (wo == NULL || wo->type != omapi_type_waiter)
waiter = NULL;
else
waiter = (omapi_waiter_object_t *)wo;
FD_ZERO(&r);
FD_ZERO(&w);
FD_ZERO(&x);
/*
* First, see if the timeout has expired, and if so return.
*/
if (t != NULL) {
gettimeofday(&now, NULL);
cur_time = now.tv_sec;
if (now.tv_sec > t->tv_sec ||
(now.tv_sec == t->tv_sec && now.tv_usec >= t->tv_usec))
return (ISC_R_TIMEDOUT);
/*
* We didn't time out, so figure out how long until we do.
*/
to.tv_sec = t->tv_sec - now.tv_sec;
to.tv_usec = t->tv_usec - now.tv_usec;
if (to.tv_usec < 0) {
to.tv_usec += 1000000;
to.tv_sec--;
}
}
/*
* If the object we're waiting on has reached completion,
* return now.
*/
if (waiter != NULL && waiter->ready != 0)
return (ISC_R_SUCCESS);
/*
* If we have no I/O state, we can't proceed.
*/
io = omapi_io_states.next;
if (io == NULL)
return (ISC_R_NOMORE);
/*
* Set up the read and write masks.
*/
for (; io != NULL; io = io->next) {
/*
* Check for a read socket. If we shouldn't be
* trying to read for this I/O object, either there
* won't be a readfd function, or it'll return -1.
*/
if (io->readfd != NULL) {
desc = (*(io->readfd))(io->inner);
FD_SET(desc, &r);
if (desc > max)
max = desc;
}
/*
* Same deal for write fdsets.
*/
if (io->writefd != NULL) {
desc = (*(io->writefd))(io->inner);
FD_SET(desc, &w);
if (desc > max)
max = desc;
}
}
/*
* Wait for a packet or a timeout. XXXTL
*/
count = select(max + 1, &r, &w, &x, t ? &to : NULL);
/*
* Get the current time.
*/
gettimeofday(&now, NULL);
cur_time = now.tv_sec;
/*
* Not likely to be transitory.
*/
if (count < 0)
return (ISC_R_UNEXPECTED);
for (io = omapi_io_states.next; io != NULL; io = io->next) {
/*
* Check for a read descriptor, and if there is one,
* see if we got input on that socket.
*/
if (io->readfd != NULL &&
(desc = (*(io->readfd))(io->inner)) >= 0) {
if (FD_ISSET(desc, &r))
result = (*(io->reader))(io->inner);
/* XXXTL what to do with result? */
}
/*
* Same deal for write descriptors.
*/
if (io->writefd != NULL &&
(desc = (*(io->writefd))(io->inner)) >= 0) {
if (FD_ISSET(desc, &w))
result = (*(io->writer))(io->inner);
/* XXX what to do with result? */
}
}
/*
* Now check for I/O handles that are no longer valid,
* and remove them from the list.
*/
prev = NULL;
for (io = omapi_io_states.next; io != NULL; io = io->next) {
if (io->reaper != NULL) {
result = (*(io->reaper))(io->inner);
if (result != ISC_R_SUCCESS) {
omapi_io_object_t *tmp = NULL;
/*
* Save a reference to the next
* pointer, if there is one.
*/
if (io->next != NULL)
OBJECT_REF(&tmp, io->next, "omapi_wfc");
if (prev != NULL) {
OBJECT_DEREF(&prev->next, "omapi_wfc");
if (tmp != NULL)
OBJECT_REF(&prev->next, tmp,
"omapi_wfc");
} else {
OBJECT_DEREF(&omapi_io_states.next,
"omapi_wfc");
if (tmp != NULL)
OBJECT_REF(&omapi_io_states.next,
tmp, "omapi_wfc");
else
omapi_signal_in
((omapi_object_t *)
&omapi_io_states,
"ready");
}
if (tmp != NULL)
OBJECT_DEREF(&tmp, "omapi_wfc");
}
}
prev = io;
}
return (ISC_R_SUCCESS);
}
isc_result_t
omapi_io_setvalue(omapi_object_t *io, omapi_object_t *id,
omapi_data_string_t *name, omapi_typed_data_t *value)
@@ -319,11 +86,14 @@ isc_result_t
omapi_waiter_signal_handler(omapi_object_t *h, const char *name, va_list ap) {
omapi_waiter_object_t *waiter;
fprintf(stderr, "omapi_waiter_signal_handler\n");
REQUIRE(h != NULL && h->type == omapi_type_waiter);
if (strcmp(name, "ready") == 0) {
fprintf(stderr, "unblocking waiter\n");
waiter = (omapi_waiter_object_t *)h;
waiter->ready = 1;
isc_condition_signal(&waiter->ready);
return (ISC_R_SUCCESS);
}

View File

@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: generic.c,v 1.5 2000/01/06 23:52:59 tale Exp $ */
/* $Id: generic.c,v 1.6 2000/01/13 06:13:22 tale Exp $ */
/* Principal Author: Ted Lemon */
@@ -53,7 +53,7 @@ omapi_generic_set_value(omapi_object_t *h, omapi_object_t *id,
omapi_value_t *new;
omapi_value_t **va;
int vm_new;
int i;
unsigned int i;
isc_result_t result;
REQUIRE(h != NULL && h->type == omapi_type_generic);
@@ -129,12 +129,13 @@ omapi_generic_set_value(omapi_object_t *h, omapi_object_t *id,
* name/value pair if necessary.
*/
if (g->nvalues == g->va_max) {
if (g->va_max != 0)
vm_new = 2 * g->va_max;
else
vm_new = 10;
/*
* Increase the maximum number of values by 10.
* 10 is an arbitrary constant.
*/
vm_new = g->va_max + 10;
va = isc_mem_get(omapi_mctx, vm_new * sizeof(*va));
if (va != NULL)
if (va == NULL)
return (ISC_R_NOMEMORY);
if (g->va_max != 0) {
memcpy(va, g->values, g->va_max * sizeof(*va));
@@ -164,7 +165,7 @@ isc_result_t
omapi_generic_get_value(omapi_object_t *h, omapi_object_t *id,
omapi_data_string_t *name, omapi_value_t **value)
{
int i;
unsigned int i;
omapi_generic_object_t *g;
REQUIRE(h != NULL && h->type == omapi_type_generic);
@@ -181,7 +182,7 @@ omapi_generic_get_value(omapi_object_t *h, omapi_object_t *id,
* same as if there were no value that matched
* the specified name, so return ISC_R_NOTFOUND.
*/
if (g->values[i]->value != NULL)
if (g->values[i]->value == NULL)
return (ISC_R_NOTFOUND);
/*
* Otherwise, return the name/value pair.
@@ -198,7 +199,7 @@ omapi_generic_get_value(omapi_object_t *h, omapi_object_t *id,
void
omapi_generic_destroy(omapi_object_t *h, const char *name) {
omapi_generic_object_t *g;
int i;
unsigned int i;
REQUIRE(h != NULL && h->type == omapi_type_generic);
@@ -235,7 +236,7 @@ omapi_generic_stuff_values(omapi_object_t *connection, omapi_object_t *id,
omapi_object_t *h)
{
omapi_generic_object_t *src;
int i;
unsigned int i;
isc_result_t result;
REQUIRE(h != NULL && h->type == omapi_type_generic);

View File

@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: handle.c,v 1.3 2000/01/04 20:04:39 tale Exp $ */
/* $Id: handle.c,v 1.4 2000/01/13 06:13:23 tale Exp $ */
/* Principal Author: Ted Lemon */
@@ -283,7 +283,7 @@ omapi_handle_lookup_in(omapi_object_t **o, omapi_handle_t h,
omapi_handle_table_t *inner;
omapi_handle_t scale, index;
if (table != NULL || table->first > h || table->limit <= h)
if (table == NULL || table->first > h || table->limit <= h)
return (ISC_R_NOTFOUND);
/*

View File

@@ -27,6 +27,7 @@
#include <isc/boolean.h>
#include <isc/lang.h>
#include <isc/time.h>
#include <isc/result.h>
ISC_LANG_BEGINDECLS
@@ -315,6 +316,10 @@ omapi_connection_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
isc_result_t
omapi_connection_require(omapi_object_t *connection, unsigned int bytes);
isc_result_t
omapi_connection_wait(omapi_object_t *object, omapi_object_t *connection_handle,
isc_time_t *timeout);
isc_result_t
omapi_connection_copyout(unsigned char *data, omapi_object_t *connection,
unsigned int length);

View File

@@ -26,8 +26,10 @@
#include <config.h>
#include <isc/condition.h>
#include <isc/lang.h>
#include <isc/mem.h>
#include <isc/mutex.h>
#include <isc/net.h>
#include <isc/result.h>
#include <isc/socket.h>
@@ -67,9 +69,12 @@ typedef struct omapi_message_object {
typedef struct omapi_connection_object {
OMAPI_OBJECT_PREAMBLE;
isc_mutex_t mutex;
isc_socket_t *socket; /* Connection socket. */
isc_task_t *task;
unsigned int events_pending;
unsigned int events_pending; /* socket events */
unsigned int messages_expected;
isc_condition_t waiter; /* omapi_connection_wait() */
omapi_connection_state_t state;
isc_sockaddr_t remote_addr;
isc_sockaddr_t local_addr;
@@ -91,20 +96,31 @@ typedef struct omapi_connection_object {
*/
isc_uint32_t out_bytes;
isc_bufferlist_t output_buffers;
#if 0
/*
* Listener that accepted this connection.
* XXXDCL This appears to not be needed.
* ... well, now it is. but it could just be an isc_boolean_t
* that indicates whether this is a server side connection or client.
*/
omapi_object_t * listener;
#endif
isc_boolean_t is_client;
} omapi_connection_object_t;
typedef struct omapi_generic_object {
OMAPI_OBJECT_PREAMBLE;
omapi_value_t ** values;
int nvalues;
int va_max;
unsigned int nvalues;
unsigned int va_max;
} omapi_generic_object_t;
typedef struct omapi_waiter_object {
OMAPI_OBJECT_PREAMBLE;
isc_mutex_t mutex;
isc_condition_t ready;
} omapi_waiter_object_t;
/*
* Everything needs a memory context. This will likely be made a parameter
* where needed rather than a single global context. XXXDCL

View File

@@ -105,22 +105,17 @@ omapi_listener_accept(isc_task_t *task, isc_event_t *event) {
connection->task = connection_task;
connection->state = omapi_connection_connected;
connection->socket = incoming->newsocket;
connection->is_client = ISC_FALSE;
ISC_LIST_INIT(connection->input_buffers);
ISC_LIST_APPEND(connection->input_buffers, ibuffer, link);
ISC_LIST_INIT(connection->output_buffers);
ISC_LIST_APPEND(connection->output_buffers, obuffer, link);
/*
* Point the connection's listener member at the listener object.
* XXXDCL but why is this needed?
*/
listener = event->arg;
OBJECT_REF(&connection->listener, listener, "omapi_listener_accept");
/*
* Notify the listener object that a connection was made.
*/
listener = event->arg;
result = omapi_signal(listener, "connect", connection);
if (result != ISC_R_SUCCESS)
/*XXXDCL then what?!*/

View File

@@ -188,6 +188,7 @@ omapi_protocol_send_message(omapi_object_t *po, omapi_object_t *id,
omapi_object_t *c;
omapi_message_object_t *m;
omapi_message_object_t *om;
omapi_connection_object_t *connection;
isc_result_t result;
REQUIRE(po != NULL && po->type == omapi_type_protocol &&
@@ -197,6 +198,7 @@ omapi_protocol_send_message(omapi_object_t *po, omapi_object_t *id,
p = (omapi_protocol_object_t *)po;
c = (omapi_object_t *)(po->outer);
connection = (omapi_connection_object_t *)c;
m = (omapi_message_object_t *)mo;
om = (omapi_message_object_t *)omo;
@@ -300,9 +302,29 @@ omapi_protocol_send_message(omapi_object_t *po, omapi_object_t *id,
/* XXXTL Write the authenticator... */
connection_send((omapi_connection_object_t *)c);
/*
* When the client sends a message, it expects a reply.
*/
if (connection->is_client) {
result = isc_mutex_lock(&connection->mutex);
if (result != ISC_R_SUCCESS)
goto disconnect;
connection->messages_expected++;
result = isc_mutex_unlock(&connection->mutex);
if (result != ISC_R_SUCCESS)
goto disconnect;
}
connection_send(connection);
return (ISC_R_SUCCESS);
disconnect:
omapi_connection_disconnect(c, OMAPI_FORCE_DISCONNECT);
return (result);
}
isc_result_t
@@ -311,12 +333,14 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
isc_result_t result;
omapi_protocol_object_t *p;
omapi_object_t *connection;
omapi_connection_object_t *c;
isc_uint16_t nlen;
isc_uint32_t vlen;
REQUIRE(h != NULL && h->type == omapi_type_protocol);
p = (omapi_protocol_object_t *)h;
c = (omapi_connection_object_t *)p->outer;
/*
* Not a signal we recognize?
@@ -328,6 +352,11 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
connection = p->outer;
/*
* XXXDCL figure out how come when this function throws
* an error, it is not seen by the main program.
*/
/*
* We get here because we requested that we be woken up after
* some number of bytes were read, and that number of bytes
@@ -360,10 +389,37 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
return (OMAPI_R_PROTOCOLERROR);
}
result = omapi_signal_in(h->inner, "ready");
/*
* Signal omapi_connection_wait() to wake up.
* Only do this for the client side.
* XXXDCL duplicated below
*/
if (c->is_client) {
result = isc_mutex_lock(&c->mutex);
if (result != ISC_R_SUCCESS)
/* XXXDCL disconnect? */
return (result);
goto disconnect;
/*
* This is an unsigned int but on the server it will
* count below 0 for each incoming message received.
* But that's ok, because the server doesn't support
* omapi_connection_wait.
*/
c->messages_expected--;
result = isc_condition_signal(&c->waiter);
/*
* Release the lock. Contrary to what you might think
* from some documentation sources, it is necessary
* to do this for the waiting thread to unblock.
*/
if (result == ISC_R_SUCCESS)
result = isc_mutex_unlock(&c->mutex);
if (result != ISC_R_SUCCESS)
goto disconnect;
}
to_header_wait:
/*
@@ -413,11 +469,10 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
/*
* If there was any extra header data, skip over it.
*/
if (p->header_size > sizeof(omapi_protocol_header_t)) {
omapi_connection_copyout(0, connection,
if (p->header_size > sizeof(omapi_protocol_header_t))
omapi_connection_copyout(NULL, connection,
(p->header_size -
sizeof(omapi_protocol_header_t)));
}
/*
* XXXTL must compute partial signature across the preceding
@@ -530,7 +585,8 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
* Wait for a 32-bit length.
*/
p->state = omapi_protocol_value_length_wait;
if (omapi_connection_require(connection, 4) != ISC_R_SUCCESS)
result = omapi_connection_require(connection, 4);
if (result != ISC_R_SUCCESS)
break;
/*
@@ -548,8 +604,7 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
if (vlen == 0)
goto insert_new_value;
result = omapi_data_new(&p->value,
omapi_datatype_data, vlen,
result = omapi_data_new(&p->value, omapi_datatype_data, vlen,
"omapi_protocol_signal_handler");
if (result != ISC_R_SUCCESS) {
omapi_connection_disconnect(connection,
@@ -558,7 +613,8 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
}
p->state = omapi_protocol_value_wait;
if (omapi_connection_require(connection, vlen) != ISC_R_SUCCESS)
result = omapi_connection_require(connection, vlen);
if (result != ISC_R_SUCCESS)
break;
/*
* If it's already here, fall through.
@@ -637,13 +693,38 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
message_done:
result = omapi_message_process((omapi_object_t *)p->message,
h);
if (result != ISC_R_SUCCESS) {
omapi_connection_disconnect(connection,
OMAPI_FORCE_DISCONNECT);
return (result);
/*
* Signal omapi_connection_wait() to wake up.
* XXXDCL duplicated from above.
*/
if (c->is_client) {
result = isc_mutex_lock(&c->mutex);
if (result != ISC_R_SUCCESS)
goto disconnect;
/*
* This is an unsigned int but on the server it will
* count below 0 for each incoming message received.
* But that's ok, because the server doesn't support
* omapi_connection_wait.
*/
c->messages_expected--;
result = isc_condition_signal(&c->waiter);
if (result != ISC_R_SUCCESS)
goto disconnect;
result = isc_mutex_unlock(&c->mutex);
if (result != ISC_R_SUCCESS)
goto disconnect;
}
/* XXXTL unbind the authenticator. */
/*
* Free the message object.
*/
OBJECT_DEREF(&p->message, "omapi_protocol_signal_handler");
/*
@@ -661,6 +742,13 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
}
return (ISC_R_SUCCESS);
/* XXXDCL
* 'goto' could be avoided by wrapping the body in another function.
*/
disconnect:
omapi_connection_disconnect(connection, OMAPI_FORCE_DISCONNECT);
return (result);
}
isc_result_t

View File

@@ -262,13 +262,16 @@ omapi_signal_in(omapi_object_t *handle, const char *name, ...) {
if (handle == NULL)
return (ISC_R_NOTFOUND);
va_start(ap, name);
if (handle->type->signal_handler)
if (handle->type->signal_handler != NULL)
result = (*(handle->type->signal_handler))(handle, name, ap);
else
result = ISC_R_NOTFOUND;
va_end(ap);
return (result);
}
@@ -459,6 +462,7 @@ omapi_object_create(omapi_object_t **obj, omapi_object_t *id,
if (type->create == NULL)
return (ISC_R_NOTIMPLEMENTED);
return ((*(type->create))(obj, id));
}
@@ -468,7 +472,7 @@ omapi_object_update(omapi_object_t *obj, omapi_object_t *id,
{
omapi_generic_object_t *gsrc;
isc_result_t result;
int i;
unsigned int i;
REQUIRE(src != NULL);