mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-03 16:15:27 +00:00
checkpoint
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -243,7 +244,7 @@ send_done(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
/*
|
||||
* XXXDCL I am assuming that partial writes are not done. I hope this
|
||||
* does not prove to be incorrect. But the assumption can be tested ...
|
||||
* does not prove to be incorrect. But the assumption can be tested ...
|
||||
*/
|
||||
ENSURE(socketevent->n == connection->out_bytes &&
|
||||
socketevent->n ==
|
||||
@@ -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,8 +749,9 @@ 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);
|
||||
}
|
||||
|
@@ -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 */
|
||||
|
||||
@@ -53,23 +53,23 @@ omapi_data_new(omapi_typed_data_t **t, omapi_datatype_t type, ...) {
|
||||
s = NULL;
|
||||
|
||||
switch (type) {
|
||||
case omapi_datatype_int:
|
||||
case omapi_datatype_int:
|
||||
len = OMAPI_TYPED_DATA_INT_LEN;
|
||||
intval = va_arg(l, int);
|
||||
break;
|
||||
case omapi_datatype_string:
|
||||
case omapi_datatype_string:
|
||||
s = va_arg(l, char *);
|
||||
val = strlen(s);
|
||||
len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
|
||||
break;
|
||||
case omapi_datatype_data:
|
||||
case omapi_datatype_data:
|
||||
val = va_arg(l, unsigned int);
|
||||
len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
|
||||
break;
|
||||
case omapi_datatype_object:
|
||||
case omapi_datatype_object:
|
||||
len = OMAPI_TYPED_DATA_OBJECT_LEN;
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"unknown type in omapi_data_new: %d\n",
|
||||
type);
|
||||
@@ -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:
|
||||
case omapi_datatype_string:
|
||||
case omapi_datatype_data:
|
||||
default:
|
||||
case omapi_datatype_int:
|
||||
length = OMAPI_TYPED_DATA_INT_LEN;
|
||||
break;
|
||||
case omapi_datatype_object:
|
||||
case omapi_datatype_string:
|
||||
length = OMAPI_TYPED_DATA_NOBUFFER_LEN +
|
||||
(*h)->u.buffer.len;
|
||||
break;
|
||||
case omapi_datatype_data:
|
||||
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);
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
||||
/*
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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?!*/
|
||||
|
@@ -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");
|
||||
if (result != ISC_R_SUCCESS)
|
||||
/* XXXDCL disconnect? */
|
||||
return (result);
|
||||
/*
|
||||
* 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)
|
||||
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,9 +604,8 @@ 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,
|
||||
"omapi_protocol_signal_handler");
|
||||
result = omapi_data_new(&p->value, omapi_datatype_data, vlen,
|
||||
"omapi_protocol_signal_handler");
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
omapi_connection_disconnect(connection,
|
||||
OMAPI_FORCE_DISCONNECT);
|
||||
@@ -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
|
||||
|
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user