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.
|
* 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 */
|
/* Principal Author: Ted Lemon */
|
||||||
|
|
||||||
@@ -35,12 +35,6 @@
|
|||||||
|
|
||||||
#include <omapi/private.h>
|
#include <omapi/private.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* Forward declarations.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
connection_send(omapi_connection_object_t *connection);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Swiped from bin/tests/sdig.c.
|
* Swiped from bin/tests/sdig.c.
|
||||||
*/
|
*/
|
||||||
@@ -144,6 +138,12 @@ connect_done(isc_task_t *task, isc_event_t *event) {
|
|||||||
|
|
||||||
connection->events_pending--;
|
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) {
|
if (connectevent->result != ISC_R_SUCCESS) {
|
||||||
abandon_connection(connection, event, connectevent->result);
|
abandon_connection(connection, event, connectevent->result);
|
||||||
return;
|
return;
|
||||||
@@ -180,6 +180,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_socket_t *socket;
|
isc_socket_t *socket;
|
||||||
isc_socketevent_t *socketevent;
|
isc_socketevent_t *socketevent;
|
||||||
omapi_connection_object_t *connection;
|
omapi_connection_object_t *connection;
|
||||||
|
unsigned int original_bytes_needed;
|
||||||
|
|
||||||
socket = event->sender;
|
socket = event->sender;
|
||||||
socketevent = (isc_socketevent_t *)event;
|
socketevent = (isc_socketevent_t *)event;
|
||||||
@@ -204,21 +205,21 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
|||||||
|
|
||||||
connection->in_bytes += socketevent->n;
|
connection->in_bytes += socketevent->n;
|
||||||
|
|
||||||
|
original_bytes_needed = connection->bytes_needed;
|
||||||
|
|
||||||
while (connection->bytes_needed <= connection->in_bytes &&
|
while (connection->bytes_needed <= connection->in_bytes &&
|
||||||
connection->bytes_needed > 0)
|
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,
|
* Queue up another recv request. If the bufferlist is empty,
|
||||||
* but I haven't thought it through fully.
|
* 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)
|
if (! ISC_LIST_EMPTY(connection->input_buffers))
|
||||||
isc_socket_recvv(socket, &connection->input_buffers,
|
omapi_connection_require((omapi_object_t *)connection, 0);
|
||||||
connection->bytes_needed -
|
|
||||||
connection->in_bytes,
|
|
||||||
task, recv_done, connection);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
isc_event_free(&event);
|
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
|
* 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 &&
|
ENSURE(socketevent->n == connection->out_bytes &&
|
||||||
socketevent->n ==
|
socketevent->n ==
|
||||||
@@ -311,6 +312,7 @@ omapi_connection_toserver(omapi_object_t *protocol, const char *server_name,
|
|||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
return (result);
|
return (result);
|
||||||
|
|
||||||
|
/* XXXDCL Make cleanup better */
|
||||||
/*
|
/*
|
||||||
* Prepare the task that will wait for the connection to be made.
|
* 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);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connection->is_client = ISC_TRUE;
|
||||||
|
|
||||||
connection->task = task;
|
connection->task = task;
|
||||||
|
|
||||||
ISC_LIST_INIT(connection->input_buffers);
|
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_INIT(connection->output_buffers);
|
||||||
ISC_LIST_APPEND(connection->output_buffers, obuffer, link);
|
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.
|
* 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);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connection->events_pending++;
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,6 +504,8 @@ omapi_connection_copyout(unsigned char *dst, omapi_object_t *generic,
|
|||||||
if (size > connection->in_bytes)
|
if (size > connection->in_bytes)
|
||||||
return (ISC_R_NOMORE);
|
return (ISC_R_NOMORE);
|
||||||
|
|
||||||
|
connection->bytes_needed -= size;
|
||||||
|
|
||||||
buffer = ISC_LIST_HEAD(connection->input_buffers);
|
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)
|
if (copy_bytes > size)
|
||||||
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);
|
isc_buffer_forward(buffer, copy_bytes);
|
||||||
|
|
||||||
@@ -639,21 +670,77 @@ omapi_connection_require(omapi_object_t *generic, unsigned int bytes) {
|
|||||||
/*
|
/*
|
||||||
* Queue the receive task.
|
* Queue the receive task.
|
||||||
* XXXDCL The "minimum" argument has not been fully thought out.
|
* 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,
|
isc_socket_recvv(connection->socket, &connection->input_buffers,
|
||||||
connection->bytes_needed - connection->in_bytes,
|
connection->bytes_needed - connection->in_bytes,
|
||||||
connection->task, recv_done, connection);
|
connection->task, recv_done, connection);
|
||||||
|
|
||||||
|
connection->events_pending++;
|
||||||
|
|
||||||
return (OMAPI_R_NOTYET);
|
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
|
isc_result_t
|
||||||
omapi_connection_setvalue(omapi_object_t *connection, omapi_object_t *id,
|
omapi_connection_setvalue(omapi_object_t *connection, omapi_object_t *id,
|
||||||
omapi_data_string_t *name, omapi_typed_data_t *value)
|
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);
|
PASS_SETVALUE(connection);
|
||||||
}
|
}
|
||||||
@@ -662,8 +749,9 @@ isc_result_t
|
|||||||
omapi_connection_getvalue(omapi_object_t *connection, omapi_object_t *id,
|
omapi_connection_getvalue(omapi_object_t *connection, omapi_object_t *id,
|
||||||
omapi_data_string_t *name, omapi_value_t **value)
|
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);
|
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);
|
REQUIRE(handle != NULL && handle->type == omapi_type_connection);
|
||||||
|
|
||||||
|
(void)name;
|
||||||
|
|
||||||
connection = (omapi_connection_object_t *)handle;
|
connection = (omapi_connection_object_t *)handle;
|
||||||
|
|
||||||
if (connection->state == omapi_connection_connected)
|
if (connection->state == omapi_connection_connected)
|
||||||
omapi_connection_disconnect(handle, OMAPI_FORCE_DISCONNECT);
|
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
|
isc_result_t
|
||||||
omapi_connection_signalhandler(omapi_object_t *connection, const char *name,
|
omapi_connection_signalhandler(omapi_object_t *connection, const char *name,
|
||||||
va_list ap)
|
va_list ap)
|
||||||
{
|
{
|
||||||
REQUIRE(connection != NULL && connection->type == omapi_type_connection);
|
REQUIRE(connection != NULL &&
|
||||||
|
connection->type == omapi_type_connection);
|
||||||
|
|
||||||
PASS_SIGNAL(connection);
|
PASS_SIGNAL(connection);
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* SOFTWARE.
|
* 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 */
|
/* Principal Author: Ted Lemon */
|
||||||
|
|
||||||
@@ -53,23 +53,23 @@ omapi_data_new(omapi_typed_data_t **t, omapi_datatype_t type, ...) {
|
|||||||
s = NULL;
|
s = NULL;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case omapi_datatype_int:
|
case omapi_datatype_int:
|
||||||
len = OMAPI_TYPED_DATA_INT_LEN;
|
len = OMAPI_TYPED_DATA_INT_LEN;
|
||||||
intval = va_arg(l, int);
|
intval = va_arg(l, int);
|
||||||
break;
|
break;
|
||||||
case omapi_datatype_string:
|
case omapi_datatype_string:
|
||||||
s = va_arg(l, char *);
|
s = va_arg(l, char *);
|
||||||
val = strlen(s);
|
val = strlen(s);
|
||||||
len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
|
len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
|
||||||
break;
|
break;
|
||||||
case omapi_datatype_data:
|
case omapi_datatype_data:
|
||||||
val = va_arg(l, unsigned int);
|
val = va_arg(l, unsigned int);
|
||||||
len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
|
len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
|
||||||
break;
|
break;
|
||||||
case omapi_datatype_object:
|
case omapi_datatype_object:
|
||||||
len = OMAPI_TYPED_DATA_OBJECT_LEN;
|
len = OMAPI_TYPED_DATA_OBJECT_LEN;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||||
"unknown type in omapi_data_new: %d\n",
|
"unknown type in omapi_data_new: %d\n",
|
||||||
type);
|
type);
|
||||||
@@ -108,7 +108,7 @@ omapi_data_reference(omapi_typed_data_t **r, omapi_typed_data_t *h,
|
|||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
REQUIRE(r != NULL && h != NULL);
|
REQUIRE(r != NULL && h != NULL);
|
||||||
REQUIRE(*r != NULL);
|
REQUIRE(*r == NULL);
|
||||||
|
|
||||||
(void)name; /* Unused. */
|
(void)name; /* Unused. */
|
||||||
|
|
||||||
@@ -118,22 +118,40 @@ omapi_data_reference(omapi_typed_data_t **r, omapi_typed_data_t *h,
|
|||||||
|
|
||||||
void
|
void
|
||||||
omapi_data_dereference(omapi_typed_data_t **h, const char *name) {
|
omapi_data_dereference(omapi_typed_data_t **h, const char *name) {
|
||||||
|
int length = 0;
|
||||||
|
|
||||||
|
|
||||||
REQUIRE(h != NULL && *h != NULL);
|
REQUIRE(h != NULL && *h != NULL);
|
||||||
REQUIRE((*h)->refcnt > 0);
|
REQUIRE((*h)->refcnt > 0);
|
||||||
|
|
||||||
if (--((*h)->refcnt) <= 0) {
|
if (--((*h)->refcnt) <= 0) {
|
||||||
switch ((*h)->type) {
|
switch ((*h)->type) {
|
||||||
case omapi_datatype_int:
|
case omapi_datatype_int:
|
||||||
case omapi_datatype_string:
|
length = OMAPI_TYPED_DATA_INT_LEN;
|
||||||
case omapi_datatype_data:
|
|
||||||
default:
|
|
||||||
break;
|
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);
|
OBJECT_DEREF(&(*h)->u.object, name);
|
||||||
|
length = OMAPI_TYPED_DATA_OBJECT_LEN;
|
||||||
break;
|
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;
|
*h = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +162,7 @@ omapi_data_newstring(omapi_data_string_t **d, unsigned int len,
|
|||||||
omapi_data_string_t *new;
|
omapi_data_string_t *new;
|
||||||
|
|
||||||
new = isc_mem_get(omapi_mctx, OMAPI_DATA_STRING_EMPTY_SIZE + len);
|
new = isc_mem_get(omapi_mctx, OMAPI_DATA_STRING_EMPTY_SIZE + len);
|
||||||
if (new != NULL)
|
if (new == NULL)
|
||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
memset(new, 0, OMAPI_DATA_STRING_EMPTY_SIZE);
|
memset(new, 0, OMAPI_DATA_STRING_EMPTY_SIZE);
|
||||||
new->len = len;
|
new->len = len;
|
||||||
@@ -186,7 +204,7 @@ omapi_data_newvalue(omapi_value_t **d, const char *name) {
|
|||||||
omapi_value_t *new;
|
omapi_value_t *new;
|
||||||
|
|
||||||
new = isc_mem_get(omapi_mctx, sizeof(*new));
|
new = isc_mem_get(omapi_mctx, sizeof(*new));
|
||||||
if (new != NULL)
|
if (new == NULL)
|
||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
memset(new, 0, sizeof *new);
|
memset(new, 0, sizeof *new);
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* SOFTWARE.
|
* 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 */
|
/* Principal Author: Ted Lemon */
|
||||||
|
|
||||||
@@ -30,25 +30,6 @@
|
|||||||
|
|
||||||
#include <omapi/private.h>
|
#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
|
isc_result_t
|
||||||
omapi_dispatch(struct timeval *t) {
|
omapi_dispatch(struct timeval *t) {
|
||||||
/*
|
/*
|
||||||
@@ -59,220 +40,6 @@ omapi_dispatch(struct timeval *t) {
|
|||||||
return (ISC_R_SUCCESS);
|
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
|
isc_result_t
|
||||||
omapi_io_setvalue(omapi_object_t *io, omapi_object_t *id,
|
omapi_io_setvalue(omapi_object_t *io, omapi_object_t *id,
|
||||||
omapi_data_string_t *name, omapi_typed_data_t *value)
|
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_signal_handler(omapi_object_t *h, const char *name, va_list ap) {
|
||||||
omapi_waiter_object_t *waiter;
|
omapi_waiter_object_t *waiter;
|
||||||
|
|
||||||
|
fprintf(stderr, "omapi_waiter_signal_handler\n");
|
||||||
|
|
||||||
REQUIRE(h != NULL && h->type == omapi_type_waiter);
|
REQUIRE(h != NULL && h->type == omapi_type_waiter);
|
||||||
|
|
||||||
if (strcmp(name, "ready") == 0) {
|
if (strcmp(name, "ready") == 0) {
|
||||||
|
fprintf(stderr, "unblocking waiter\n");
|
||||||
waiter = (omapi_waiter_object_t *)h;
|
waiter = (omapi_waiter_object_t *)h;
|
||||||
waiter->ready = 1;
|
isc_condition_signal(&waiter->ready);
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* SOFTWARE.
|
* 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 */
|
/* 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 *new;
|
||||||
omapi_value_t **va;
|
omapi_value_t **va;
|
||||||
int vm_new;
|
int vm_new;
|
||||||
int i;
|
unsigned int i;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
|
||||||
REQUIRE(h != NULL && h->type == omapi_type_generic);
|
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.
|
* name/value pair if necessary.
|
||||||
*/
|
*/
|
||||||
if (g->nvalues == g->va_max) {
|
if (g->nvalues == g->va_max) {
|
||||||
if (g->va_max != 0)
|
/*
|
||||||
vm_new = 2 * g->va_max;
|
* Increase the maximum number of values by 10.
|
||||||
else
|
* 10 is an arbitrary constant.
|
||||||
vm_new = 10;
|
*/
|
||||||
|
vm_new = g->va_max + 10;
|
||||||
va = isc_mem_get(omapi_mctx, vm_new * sizeof(*va));
|
va = isc_mem_get(omapi_mctx, vm_new * sizeof(*va));
|
||||||
if (va != NULL)
|
if (va == NULL)
|
||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
if (g->va_max != 0) {
|
if (g->va_max != 0) {
|
||||||
memcpy(va, g->values, g->va_max * sizeof(*va));
|
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_generic_get_value(omapi_object_t *h, omapi_object_t *id,
|
||||||
omapi_data_string_t *name, omapi_value_t **value)
|
omapi_data_string_t *name, omapi_value_t **value)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned int i;
|
||||||
omapi_generic_object_t *g;
|
omapi_generic_object_t *g;
|
||||||
|
|
||||||
REQUIRE(h != NULL && h->type == omapi_type_generic);
|
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
|
* same as if there were no value that matched
|
||||||
* the specified name, so return ISC_R_NOTFOUND.
|
* the specified name, so return ISC_R_NOTFOUND.
|
||||||
*/
|
*/
|
||||||
if (g->values[i]->value != NULL)
|
if (g->values[i]->value == NULL)
|
||||||
return (ISC_R_NOTFOUND);
|
return (ISC_R_NOTFOUND);
|
||||||
/*
|
/*
|
||||||
* Otherwise, return the name/value pair.
|
* Otherwise, return the name/value pair.
|
||||||
@@ -198,7 +199,7 @@ omapi_generic_get_value(omapi_object_t *h, omapi_object_t *id,
|
|||||||
void
|
void
|
||||||
omapi_generic_destroy(omapi_object_t *h, const char *name) {
|
omapi_generic_destroy(omapi_object_t *h, const char *name) {
|
||||||
omapi_generic_object_t *g;
|
omapi_generic_object_t *g;
|
||||||
int i;
|
unsigned int i;
|
||||||
|
|
||||||
REQUIRE(h != NULL && h->type == omapi_type_generic);
|
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_object_t *h)
|
||||||
{
|
{
|
||||||
omapi_generic_object_t *src;
|
omapi_generic_object_t *src;
|
||||||
int i;
|
unsigned int i;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
|
||||||
REQUIRE(h != NULL && h->type == omapi_type_generic);
|
REQUIRE(h != NULL && h->type == omapi_type_generic);
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* SOFTWARE.
|
* 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 */
|
/* 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_table_t *inner;
|
||||||
omapi_handle_t scale, index;
|
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);
|
return (ISC_R_NOTFOUND);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include <isc/boolean.h>
|
#include <isc/boolean.h>
|
||||||
#include <isc/lang.h>
|
#include <isc/lang.h>
|
||||||
|
#include <isc/time.h>
|
||||||
#include <isc/result.h>
|
#include <isc/result.h>
|
||||||
|
|
||||||
ISC_LANG_BEGINDECLS
|
ISC_LANG_BEGINDECLS
|
||||||
@@ -315,6 +316,10 @@ omapi_connection_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
|
|||||||
isc_result_t
|
isc_result_t
|
||||||
omapi_connection_require(omapi_object_t *connection, unsigned int bytes);
|
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
|
isc_result_t
|
||||||
omapi_connection_copyout(unsigned char *data, omapi_object_t *connection,
|
omapi_connection_copyout(unsigned char *data, omapi_object_t *connection,
|
||||||
unsigned int length);
|
unsigned int length);
|
||||||
|
@@ -26,8 +26,10 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <isc/condition.h>
|
||||||
#include <isc/lang.h>
|
#include <isc/lang.h>
|
||||||
#include <isc/mem.h>
|
#include <isc/mem.h>
|
||||||
|
#include <isc/mutex.h>
|
||||||
#include <isc/net.h>
|
#include <isc/net.h>
|
||||||
#include <isc/result.h>
|
#include <isc/result.h>
|
||||||
#include <isc/socket.h>
|
#include <isc/socket.h>
|
||||||
@@ -67,9 +69,12 @@ typedef struct omapi_message_object {
|
|||||||
|
|
||||||
typedef struct omapi_connection_object {
|
typedef struct omapi_connection_object {
|
||||||
OMAPI_OBJECT_PREAMBLE;
|
OMAPI_OBJECT_PREAMBLE;
|
||||||
|
isc_mutex_t mutex;
|
||||||
isc_socket_t *socket; /* Connection socket. */
|
isc_socket_t *socket; /* Connection socket. */
|
||||||
isc_task_t *task;
|
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;
|
omapi_connection_state_t state;
|
||||||
isc_sockaddr_t remote_addr;
|
isc_sockaddr_t remote_addr;
|
||||||
isc_sockaddr_t local_addr;
|
isc_sockaddr_t local_addr;
|
||||||
@@ -91,20 +96,31 @@ typedef struct omapi_connection_object {
|
|||||||
*/
|
*/
|
||||||
isc_uint32_t out_bytes;
|
isc_uint32_t out_bytes;
|
||||||
isc_bufferlist_t output_buffers;
|
isc_bufferlist_t output_buffers;
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
* Listener that accepted this connection.
|
* Listener that accepted this connection.
|
||||||
* XXXDCL This appears to not be needed.
|
* 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;
|
omapi_object_t * listener;
|
||||||
|
#endif
|
||||||
|
isc_boolean_t is_client;
|
||||||
} omapi_connection_object_t;
|
} omapi_connection_object_t;
|
||||||
|
|
||||||
typedef struct omapi_generic_object {
|
typedef struct omapi_generic_object {
|
||||||
OMAPI_OBJECT_PREAMBLE;
|
OMAPI_OBJECT_PREAMBLE;
|
||||||
omapi_value_t ** values;
|
omapi_value_t ** values;
|
||||||
int nvalues;
|
unsigned int nvalues;
|
||||||
int va_max;
|
unsigned int va_max;
|
||||||
} omapi_generic_object_t;
|
} 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
|
* Everything needs a memory context. This will likely be made a parameter
|
||||||
* where needed rather than a single global context. XXXDCL
|
* 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->task = connection_task;
|
||||||
connection->state = omapi_connection_connected;
|
connection->state = omapi_connection_connected;
|
||||||
connection->socket = incoming->newsocket;
|
connection->socket = incoming->newsocket;
|
||||||
|
connection->is_client = ISC_FALSE;
|
||||||
|
|
||||||
ISC_LIST_INIT(connection->input_buffers);
|
ISC_LIST_INIT(connection->input_buffers);
|
||||||
ISC_LIST_APPEND(connection->input_buffers, ibuffer, link);
|
ISC_LIST_APPEND(connection->input_buffers, ibuffer, link);
|
||||||
ISC_LIST_INIT(connection->output_buffers);
|
ISC_LIST_INIT(connection->output_buffers);
|
||||||
ISC_LIST_APPEND(connection->output_buffers, obuffer, link);
|
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.
|
* Notify the listener object that a connection was made.
|
||||||
*/
|
*/
|
||||||
|
listener = event->arg;
|
||||||
result = omapi_signal(listener, "connect", connection);
|
result = omapi_signal(listener, "connect", connection);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
/*XXXDCL then what?!*/
|
/*XXXDCL then what?!*/
|
||||||
|
@@ -188,6 +188,7 @@ omapi_protocol_send_message(omapi_object_t *po, omapi_object_t *id,
|
|||||||
omapi_object_t *c;
|
omapi_object_t *c;
|
||||||
omapi_message_object_t *m;
|
omapi_message_object_t *m;
|
||||||
omapi_message_object_t *om;
|
omapi_message_object_t *om;
|
||||||
|
omapi_connection_object_t *connection;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
|
||||||
REQUIRE(po != NULL && po->type == omapi_type_protocol &&
|
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;
|
p = (omapi_protocol_object_t *)po;
|
||||||
c = (omapi_object_t *)(po->outer);
|
c = (omapi_object_t *)(po->outer);
|
||||||
|
connection = (omapi_connection_object_t *)c;
|
||||||
m = (omapi_message_object_t *)mo;
|
m = (omapi_message_object_t *)mo;
|
||||||
om = (omapi_message_object_t *)omo;
|
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... */
|
/* 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);
|
return (ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
disconnect:
|
||||||
|
omapi_connection_disconnect(c, OMAPI_FORCE_DISCONNECT);
|
||||||
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
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;
|
isc_result_t result;
|
||||||
omapi_protocol_object_t *p;
|
omapi_protocol_object_t *p;
|
||||||
omapi_object_t *connection;
|
omapi_object_t *connection;
|
||||||
|
omapi_connection_object_t *c;
|
||||||
isc_uint16_t nlen;
|
isc_uint16_t nlen;
|
||||||
isc_uint32_t vlen;
|
isc_uint32_t vlen;
|
||||||
|
|
||||||
REQUIRE(h != NULL && h->type == omapi_type_protocol);
|
REQUIRE(h != NULL && h->type == omapi_type_protocol);
|
||||||
|
|
||||||
p = (omapi_protocol_object_t *)h;
|
p = (omapi_protocol_object_t *)h;
|
||||||
|
c = (omapi_connection_object_t *)p->outer;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Not a signal we recognize?
|
* 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;
|
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
|
* We get here because we requested that we be woken up after
|
||||||
* some number of bytes were read, and that number of bytes
|
* 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);
|
return (OMAPI_R_PROTOCOLERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = omapi_signal_in(h->inner, "ready");
|
/*
|
||||||
if (result != ISC_R_SUCCESS)
|
* Signal omapi_connection_wait() to wake up.
|
||||||
/* XXXDCL disconnect? */
|
* Only do this for the client side.
|
||||||
return (result);
|
* 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:
|
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 there was any extra header data, skip over it.
|
||||||
*/
|
*/
|
||||||
if (p->header_size > sizeof(omapi_protocol_header_t)) {
|
if (p->header_size > sizeof(omapi_protocol_header_t))
|
||||||
omapi_connection_copyout(0, connection,
|
omapi_connection_copyout(NULL, connection,
|
||||||
(p->header_size -
|
(p->header_size -
|
||||||
sizeof(omapi_protocol_header_t)));
|
sizeof(omapi_protocol_header_t)));
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXXTL must compute partial signature across the preceding
|
* 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.
|
* Wait for a 32-bit length.
|
||||||
*/
|
*/
|
||||||
p->state = omapi_protocol_value_length_wait;
|
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;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -548,9 +604,8 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
|
|||||||
if (vlen == 0)
|
if (vlen == 0)
|
||||||
goto insert_new_value;
|
goto insert_new_value;
|
||||||
|
|
||||||
result = omapi_data_new(&p->value,
|
result = omapi_data_new(&p->value, omapi_datatype_data, vlen,
|
||||||
omapi_datatype_data, vlen,
|
"omapi_protocol_signal_handler");
|
||||||
"omapi_protocol_signal_handler");
|
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
omapi_connection_disconnect(connection,
|
omapi_connection_disconnect(connection,
|
||||||
OMAPI_FORCE_DISCONNECT);
|
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;
|
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;
|
break;
|
||||||
/*
|
/*
|
||||||
* If it's already here, fall through.
|
* 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:
|
message_done:
|
||||||
result = omapi_message_process((omapi_object_t *)p->message,
|
result = omapi_message_process((omapi_object_t *)p->message,
|
||||||
h);
|
h);
|
||||||
if (result != ISC_R_SUCCESS) {
|
|
||||||
omapi_connection_disconnect(connection,
|
/*
|
||||||
OMAPI_FORCE_DISCONNECT);
|
* Signal omapi_connection_wait() to wake up.
|
||||||
return (result);
|
* 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. */
|
/* XXXTL unbind the authenticator. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free the message object.
|
||||||
|
*/
|
||||||
OBJECT_DEREF(&p->message, "omapi_protocol_signal_handler");
|
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);
|
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
|
isc_result_t
|
||||||
|
@@ -262,13 +262,16 @@ omapi_signal_in(omapi_object_t *handle, const char *name, ...) {
|
|||||||
|
|
||||||
if (handle == NULL)
|
if (handle == NULL)
|
||||||
return (ISC_R_NOTFOUND);
|
return (ISC_R_NOTFOUND);
|
||||||
|
|
||||||
va_start(ap, name);
|
va_start(ap, name);
|
||||||
|
|
||||||
if (handle->type->signal_handler)
|
if (handle->type->signal_handler != NULL)
|
||||||
result = (*(handle->type->signal_handler))(handle, name, ap);
|
result = (*(handle->type->signal_handler))(handle, name, ap);
|
||||||
else
|
else
|
||||||
result = ISC_R_NOTFOUND;
|
result = ISC_R_NOTFOUND;
|
||||||
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,6 +462,7 @@ omapi_object_create(omapi_object_t **obj, omapi_object_t *id,
|
|||||||
|
|
||||||
if (type->create == NULL)
|
if (type->create == NULL)
|
||||||
return (ISC_R_NOTIMPLEMENTED);
|
return (ISC_R_NOTIMPLEMENTED);
|
||||||
|
|
||||||
return ((*(type->create))(obj, id));
|
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;
|
omapi_generic_object_t *gsrc;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
int i;
|
unsigned int i;
|
||||||
|
|
||||||
REQUIRE(src != NULL);
|
REQUIRE(src != NULL);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user