mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 05:28:00 +00:00
checkpoint
This commit is contained in:
parent
9ff3698b6d
commit
eb421ff1a1
@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: connection.c,v 1.8 2000/01/14 23:10:01 tale Exp $ */
|
||||
/* $Id: connection.c,v 1.9 2000/01/17 18:02:04 tale Exp $ */
|
||||
|
||||
/* Principal Author: Ted Lemon */
|
||||
|
||||
@ -88,6 +88,12 @@ free_connection(omapi_connection_object_t *connection) {
|
||||
*/
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* This one is locked too, unlock it so it can be destroyed.
|
||||
*/
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->recv_lock) ==
|
||||
ISC_R_SUCCESS);
|
||||
|
||||
while ((buffer = ISC_LIST_HEAD(connection->input_buffers)) != NULL) {
|
||||
ISC_LIST_UNLINK(connection->input_buffers, buffer, link);
|
||||
isc_buffer_free(&buffer);
|
||||
@ -104,37 +110,11 @@ free_connection(omapi_connection_object_t *connection) {
|
||||
if (connection->socket != NULL)
|
||||
isc_socket_detach(&connection->socket);
|
||||
|
||||
/*
|
||||
* It is possible the connection was abandoned while a message
|
||||
* was being assembled. That thread needs to be unblocked.
|
||||
* Make sure that when it is awakened, it exits the loop by
|
||||
* setting messages_expected to 0.
|
||||
*/
|
||||
if (connection->is_client) {
|
||||
connection->messages_expected = 0;
|
||||
|
||||
REQUIRE(isc_condition_signal(&connection->waiter) ==
|
||||
ISC_R_SUCCESS);
|
||||
RUNTIME_CHECK(isc_condition_destroy(&connection->waiter) ==
|
||||
ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
/* XXXDCL ok, but what happens when omapi_connection_wait
|
||||
* awakens and then tries to unlock the mutex, which is possibly
|
||||
* being destroyed right here. i don't think relocking is
|
||||
* a guarantee that isc_condition_wait exited and the mutex was
|
||||
* unlocked in omapi_connection_wait. still, it's worth a shot.
|
||||
*/
|
||||
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS);
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == ISC_R_SUCCESS);
|
||||
RUNTIME_CHECK(isc_mutex_destroy(&connection->mutex) == ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Disconnect from I/O object, if any.
|
||||
*/
|
||||
if (connection->outer != NULL)
|
||||
OBJECT_DEREF(&connection->outer,
|
||||
"omapi_connection_disconnect");
|
||||
RUNTIME_CHECK(isc_mutex_destroy(&connection->recv_lock) ==
|
||||
ISC_R_SUCCESS);
|
||||
RUNTIME_CHECK(isc_condition_destroy(&connection->waiter) ==
|
||||
ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* If whatever created us registered a signal handler, send it
|
||||
@ -142,10 +122,20 @@ free_connection(omapi_connection_object_t *connection) {
|
||||
*/
|
||||
omapi_signal((omapi_object_t *)connection, "disconnect", connection);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Free the inner generic object via the protocol object.
|
||||
* XXXDCL wildass stab in the dark
|
||||
*/
|
||||
OBJECT_DEREF(&connection->inner->inner);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Finally, free the object itself.
|
||||
*/
|
||||
OBJECT_DEREF(&connection, "free_connection");
|
||||
OBJECT_DEREF(&connection);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -161,6 +151,12 @@ end_connection(omapi_connection_object_t *connection, isc_event_t *event,
|
||||
* think this can be done with the connection as the object.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Don't proceed until recv_done() has finished whatever
|
||||
* it was doing that decremented events_pending to 0.
|
||||
*/
|
||||
RUNTIME_CHECK(isc_mutex_lock(&connection->recv_lock) == ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Lock the connection's mutex to examine connection->events_pending.
|
||||
*/
|
||||
@ -170,11 +166,37 @@ end_connection(omapi_connection_object_t *connection, isc_event_t *event,
|
||||
connection->events_pending);
|
||||
|
||||
if (connection->events_pending == 0) {
|
||||
free_connection(connection);
|
||||
if (connection->waiting) {
|
||||
/*
|
||||
* This must have been an error, since
|
||||
* omapi_connection_wait can't be called after
|
||||
* omapi_connection_disconnect is called for
|
||||
* a normal close.
|
||||
*
|
||||
* Signal omapi_connection_wait and have it do the
|
||||
* cleanup. free_connection can't be called
|
||||
* directly here because it can't be sure
|
||||
* that the mutex has been finished being touched
|
||||
* by omapi_connection_wait even if it
|
||||
* free_connection signals it. (Nasty little
|
||||
* race condition with the lock.)
|
||||
*
|
||||
* Make sure that when it is awakened, it exits its
|
||||
* wait loop by setting messages_expected to 0.
|
||||
*/
|
||||
connection->state = omapi_connection_closed;
|
||||
connection->messages_expected = 0;
|
||||
|
||||
RUNTIME_CHECK(isc_condition_signal(&connection->waiter)
|
||||
== ISC_R_SUCCESS);
|
||||
} else
|
||||
free_connection(connection);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == ISC_R_SUCCESS);
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->recv_lock) ==
|
||||
ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
@ -208,7 +230,7 @@ connect_done(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
fprintf(stderr, "CONNECT_DONE\n");
|
||||
|
||||
ENSURE(socket == connection->socket && task == connection->task);
|
||||
INSIST(socket == connection->socket && task == connection->task);
|
||||
|
||||
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS);
|
||||
/*
|
||||
@ -217,7 +239,7 @@ connect_done(isc_task_t *task, isc_event_t *event) {
|
||||
* only in recv_done. I'm concerned that there might be some
|
||||
* sort of logic window, however small, where that isn't true.
|
||||
*/
|
||||
ENSURE(connection->events_pending > 0);
|
||||
INSIST(connection->events_pending > 0);
|
||||
if (--connection->events_pending == 0 && connection->is_client &&
|
||||
connection->state == omapi_connection_disconnecting)
|
||||
FATAL_ERROR(__FILE__, __LINE__,
|
||||
@ -273,10 +295,40 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
fprintf(stderr, "RECV_DONE, %d bytes\n", socketevent->n);
|
||||
|
||||
ENSURE(socket == connection->socket && task == connection->task);
|
||||
INSIST(socket == connection->socket && task == connection->task);
|
||||
|
||||
/*
|
||||
* XXXDCL This recv_lock is a dirty, ugly, nasty hack and I
|
||||
* am ashamed for it. I have struggled for days with how to
|
||||
* prevent the driving progam's call of omapi_connection_disconnect
|
||||
* from conflicting with the execution of the task thread
|
||||
* (this one, where recv_done is being called).
|
||||
*
|
||||
* Basically, most of the real work happens in the task thread,
|
||||
* all kicked off by signalling "ready" a few lines below. If
|
||||
* this recv_done() is processing the last expected bytes of a message,
|
||||
* then it will wake up the driving program, and the driving program
|
||||
* can go ahead and issue a disconnect. Since there are neither
|
||||
* events_pending nor messages_expected, end_connecton goes ahead
|
||||
* and frees the connection. But that can happen before this
|
||||
* very function can go finish up what it is doing with the
|
||||
* connection structure, which is clearly a bad thing.
|
||||
*
|
||||
* The regular mutex in the connection (the one named "mutex") is
|
||||
* being used throughout the code in a much more localized fashion,
|
||||
* and while it might be possible to more broadly scope it so that
|
||||
* it essentially does the job that recv_lock is doing, I honestly
|
||||
* have not yet fully thought that out and I have already burned
|
||||
* so much time trying other approaches before I struck on this
|
||||
* recv_lock idea. My gut reaction is I don't like how long
|
||||
* a lock on 'mutex' would be held, and I am not entirely sure
|
||||
* that there aren't deadlock situations. I have to think about it
|
||||
* ... LATER.
|
||||
*/
|
||||
RUNTIME_CHECK(isc_mutex_lock(&connection->recv_lock) == ISC_R_SUCCESS);
|
||||
|
||||
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS);
|
||||
ENSURE(connection->events_pending > 0);
|
||||
INSIST(connection->events_pending > 0);
|
||||
connection->events_pending--;
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == ISC_R_SUCCESS);
|
||||
|
||||
@ -295,13 +347,25 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
original_bytes_needed = connection->bytes_needed;
|
||||
|
||||
/*
|
||||
* Signal omapi_protocol_signal_handler that the bytes it requested
|
||||
* are present.
|
||||
*
|
||||
* XXXDCL it will then isc_condition_signal the driving thread,
|
||||
* which is free to go ahead and call omapi_connection_disconnect.
|
||||
* since there are possibly no more events pending and no more messages
|
||||
* expected at that point, the driving thread may end up freeing the
|
||||
* connection before this routine is done manipulating it.
|
||||
* what a big, ugly, pain in the rump.
|
||||
*/
|
||||
while (connection->bytes_needed <= connection->in_bytes &&
|
||||
connection->bytes_needed > 0)
|
||||
|
||||
if (omapi_signal((omapi_object_t *)connection, "ready",
|
||||
connection) !=
|
||||
ISC_R_SUCCESS)
|
||||
connection) != ISC_R_SUCCESS)
|
||||
goto abandon;
|
||||
|
||||
|
||||
/*
|
||||
* Queue up another recv request. If the bufferlist is empty,
|
||||
* then, something under omapi_signal already called
|
||||
@ -313,20 +377,37 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
/*
|
||||
* See if that was the last event the client was expecting, so
|
||||
* that the connection can be freed.
|
||||
* XXXDCL I don't *think* this has to be done in the
|
||||
* send_done or connect_done handlers, because a normal
|
||||
* termination will only happen
|
||||
* that the connection can be freed. This test needs to be
|
||||
* done, because it is possible omapi_connection_disconnect has
|
||||
* already been called, before the signal handler managed to
|
||||
* decrement messages_expected. That means that _disconnect
|
||||
* set the state to disconnecting but didn't call the
|
||||
* end_connection routine. If this was the last event,
|
||||
* no more events are going to come in and call recv_done again,
|
||||
* so this is the only time that it can be identified that
|
||||
* the conditions for finally freeing the connection are all true.
|
||||
*
|
||||
* XXXDCL I don't *think* this has to be done in the send_done or
|
||||
* connect_done handlers, because a normal termination (one defined as
|
||||
* "omapi_connection_disconnect called by the client with 'force' as
|
||||
* false") will only happen after the last of the expected data is
|
||||
* received.
|
||||
*/
|
||||
if (connection->is_client) {
|
||||
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
if (connection->events_pending == 0 &&
|
||||
connection->state == omapi_connection_disconnecting) {
|
||||
ENSURE(connection->messages_expected == 1);
|
||||
INSIST(connection->messages_expected == 1);
|
||||
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
/*
|
||||
* omapi_connection_disconnect was called, but
|
||||
* end_connection has not been. Call it now.
|
||||
*/
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex)
|
||||
== ISC_R_SUCCESS);
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->recv_lock)
|
||||
== ISC_R_SUCCESS);
|
||||
|
||||
end_connection(connection, event, ISC_R_SUCCESS);
|
||||
return;
|
||||
@ -334,11 +415,15 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
}
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->recv_lock) ==
|
||||
ISC_R_SUCCESS);
|
||||
|
||||
isc_event_free(&event);
|
||||
return;
|
||||
|
||||
abandon:
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->recv_lock) ==
|
||||
ISC_R_SUCCESS);
|
||||
end_connection(connection, event, socketevent->result);
|
||||
return;
|
||||
}
|
||||
@ -360,13 +445,13 @@ send_done(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
fprintf(stderr, "SEND_DONE, %d bytes\n", socketevent->n);
|
||||
|
||||
ENSURE(socket == connection->socket && task == connection->task);
|
||||
INSIST(socket == connection->socket && task == connection->task);
|
||||
|
||||
/*
|
||||
* 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 ...
|
||||
*/
|
||||
ENSURE(socketevent->n == connection->out_bytes &&
|
||||
INSIST(socketevent->n == connection->out_bytes &&
|
||||
socketevent->n ==
|
||||
isc_bufferlist_usedcount(&socketevent->bufferlist));
|
||||
|
||||
@ -377,7 +462,7 @@ send_done(isc_task_t *task, isc_event_t *event) {
|
||||
* only in recv_done. I'm concerned that there might be some
|
||||
* sort of logic window, however small, where that isn't true.
|
||||
*/
|
||||
ENSURE(connection->events_pending > 0);
|
||||
INSIST(connection->events_pending > 0);
|
||||
if (--connection->events_pending == 0 && connection->is_client &&
|
||||
connection->state == omapi_connection_disconnecting)
|
||||
FATAL_ERROR(__FILE__, __LINE__,
|
||||
@ -421,7 +506,7 @@ connection_send(omapi_connection_object_t *connection) {
|
||||
REQUIRE(connection->state == omapi_connection_connected);
|
||||
|
||||
if (connection->out_bytes > 0) {
|
||||
ENSURE(!ISC_LIST_EMPTY(connection->output_buffers));
|
||||
INSIST(!ISC_LIST_EMPTY(connection->output_buffers));
|
||||
|
||||
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
@ -473,12 +558,13 @@ omapi_connection_toserver(omapi_object_t *protocol, const char *server_name,
|
||||
/*
|
||||
* Create a new connection object.
|
||||
*/
|
||||
result = omapi_object_new((omapi_object_t **)&connection,
|
||||
result = omapi_object_create((omapi_object_t **)&connection,
|
||||
omapi_type_connection, sizeof(*connection));
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto free_obuffer;
|
||||
|
||||
connection->is_client = ISC_TRUE;
|
||||
connection->waiting = ISC_FALSE;
|
||||
|
||||
connection->task = task;
|
||||
|
||||
@ -488,6 +574,7 @@ omapi_connection_toserver(omapi_object_t *protocol, const char *server_name,
|
||||
ISC_LIST_APPEND(connection->output_buffers, obuffer, link);
|
||||
|
||||
RUNTIME_CHECK(isc_mutex_init(&connection->mutex) == ISC_R_SUCCESS);
|
||||
RUNTIME_CHECK(isc_mutex_init(&connection->recv_lock) == ISC_R_SUCCESS);
|
||||
RUNTIME_CHECK(isc_condition_init(&connection->waiter) ==
|
||||
ISC_R_SUCCESS);
|
||||
|
||||
@ -503,8 +590,8 @@ omapi_connection_toserver(omapi_object_t *protocol, const char *server_name,
|
||||
/*
|
||||
* Tie the new connection object to the protocol object.
|
||||
*/
|
||||
OBJECT_REF(&protocol->outer, connection, "omapi_connection_toserver");
|
||||
OBJECT_REF(&connection->inner, protocol, "omapi_connection_toserver");
|
||||
OBJECT_REF(&protocol->outer, connection);
|
||||
OBJECT_REF(&connection->inner, protocol);
|
||||
|
||||
/*
|
||||
* Create a socket on which to communicate.
|
||||
@ -522,7 +609,7 @@ omapi_connection_toserver(omapi_object_t *protocol, const char *server_name,
|
||||
flag = 1;
|
||||
if (setsockopt(connection->socket, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char *)&flag, sizeof(flag)) < 0) {
|
||||
OBJECT_DEREF(&connection, "omapi_connect");
|
||||
OBJECT_DEREF(&connection);
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
#endif
|
||||
@ -541,8 +628,8 @@ omapi_connection_toserver(omapi_object_t *protocol, const char *server_name,
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
free_object:
|
||||
OBJECT_DEREF(&connection, "omapi_connection_toserver");
|
||||
OBJECT_DEREF(&protocol->outer, "omapi_connection_toserver");
|
||||
OBJECT_DEREF(&connection);
|
||||
OBJECT_DEREF(&protocol->outer);
|
||||
return (result);
|
||||
|
||||
free_obuffer:
|
||||
@ -694,6 +781,12 @@ omapi_connection_copyout(unsigned char *dst, omapi_object_t *generic,
|
||||
* the protocol.)
|
||||
*
|
||||
* The client might or might not want to block on the disconnection.
|
||||
* Currently the way to accomplish this is to call omapi_connection_wait
|
||||
* before calling this function. A more complex method could be developed,
|
||||
* but after spending (too much) time thinking about it, it hardly seems to
|
||||
* be worth the effort when it is easy to just insist that the
|
||||
* omapi_connection_wait be done.
|
||||
*
|
||||
* Also, if the error is being thrown from the library, the client
|
||||
* might *already* be waiting on (or intending to wait on) whatever messages
|
||||
* it has already sent, so it needs to be awakened. That will be handled
|
||||
@ -733,24 +826,31 @@ omapi_connection_disconnect(omapi_object_t *generic, isc_boolean_t force) {
|
||||
*/
|
||||
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
INSIST(connection->state == omapi_connection_connected);
|
||||
|
||||
connection->state = omapi_connection_disconnecting;
|
||||
connection->messages_expected++;
|
||||
|
||||
/*
|
||||
* If there are no other messages expected for the socket,
|
||||
* the end_connection can be done right now. Otherwise,
|
||||
* when recv_done gets the last output from the server,
|
||||
* then it will then end the connection.
|
||||
* If there are other messages expected for the socket,
|
||||
* then set the state to disconnecting. Based on that
|
||||
* flag, when recv_done gets the last output from the server,
|
||||
* it will then end the connection. The reason the state
|
||||
* is set to disconnecting only here and not while falling
|
||||
* through to end_connection below is that it is the
|
||||
* flag which says whether end_connection has been called or
|
||||
* not.
|
||||
*/
|
||||
if (connection->messages_expected > 1) {
|
||||
connection->state = omapi_connection_disconnecting;
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* ... else fall through.
|
||||
*/
|
||||
INSIST(connection->events_pending == 0);
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
}
|
||||
@ -777,23 +877,7 @@ omapi_connection_require(omapi_object_t *generic, unsigned int bytes) {
|
||||
|
||||
connection = (omapi_connection_object_t *)generic;
|
||||
|
||||
/*
|
||||
* There is a race condition here that is really, REALLY
|
||||
* irritating me. Here's the latest attempt at fixing the
|
||||
* whole dang disconnect problem. It is doomed to fail ...
|
||||
* but maybe it will do the job for now.
|
||||
* XXXDCL
|
||||
*/
|
||||
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS);
|
||||
if (connection->state == omapi_connection_disconnecting &&
|
||||
connection->messages_expected == 1) {
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
return (OMAPI_R_NOTYET);
|
||||
}
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == ISC_R_SUCCESS);
|
||||
|
||||
ENSURE(connection->state == omapi_connection_connected ||
|
||||
INSIST(connection->state == omapi_connection_connected ||
|
||||
connection->state == omapi_connection_disconnecting);
|
||||
|
||||
connection->bytes_needed += bytes;
|
||||
@ -857,38 +941,15 @@ omapi_connection_require(omapi_object_t *generic, unsigned int bytes) {
|
||||
}
|
||||
|
||||
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Don't queue any more read requests if the connection is
|
||||
* disconnecting and no more messages are expected. This situation
|
||||
* can happen when omapi_connection_disconnect is called before
|
||||
* omapi_protocol_signal_handler has had a chance to go back to
|
||||
* its omapi_protocol_header_wait condition where it calls
|
||||
* omapi_connection_require. It is possible the isc_socket_cancel
|
||||
* was already done.
|
||||
* Queue the receive task.
|
||||
* XXXDCL The "minimum" arg has not been fully thought out.
|
||||
*/
|
||||
if (connection->state == omapi_connection_disconnecting &&
|
||||
connection->messages_expected == 0) {
|
||||
/*
|
||||
* Test the above comment's claim that this only happens
|
||||
* when requesting to wait for the header of the next message.
|
||||
* XXXDCL
|
||||
* (omapi_protocol_object_t *)p->inner->header_size should
|
||||
* be what is checked against, but at the present time
|
||||
* the protocol_object_t exists only in protocol.c
|
||||
*/
|
||||
ENSURE(bytes == 24);
|
||||
} else {
|
||||
/*
|
||||
* Queue the receive task.
|
||||
* XXXDCL The "minimum" arg has not been fully thought out.
|
||||
*/
|
||||
connection->events_pending++;
|
||||
isc_socket_recvv(connection->socket,
|
||||
&connection->input_buffers,
|
||||
(connection->bytes_needed -
|
||||
connection->in_bytes),
|
||||
connection->task, recv_done, connection);
|
||||
}
|
||||
connection->events_pending++;
|
||||
isc_socket_recvv(connection->socket, &connection->input_buffers,
|
||||
connection->bytes_needed - connection->in_bytes,
|
||||
connection->task, recv_done, connection);
|
||||
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
@ -903,6 +964,14 @@ omapi_connection_require(omapi_object_t *generic, unsigned int bytes) {
|
||||
* 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.
|
||||
*
|
||||
* XXXDCL ICK. There is a problem. What if an error that causes disconnection
|
||||
* is happens before it is detected by the driving program, before this
|
||||
* function has ever been called, but after all of the connection data
|
||||
* has been freed.
|
||||
*
|
||||
* Actually, that seems to be a problem throughout this WHOLE LIBRARY. It
|
||||
* really needs to be handled somehow.
|
||||
*/
|
||||
isc_result_t
|
||||
omapi_connection_wait(omapi_object_t *object,
|
||||
@ -913,7 +982,7 @@ omapi_connection_wait(omapi_object_t *object,
|
||||
* XXXDCL 'object' is not really used.
|
||||
*/
|
||||
omapi_connection_object_t *connection;
|
||||
isc_result_t result, wait_result;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
REQUIRE(object != NULL && connection_handle != NULL);
|
||||
REQUIRE(connection_handle->type == omapi_type_connection);
|
||||
@ -922,90 +991,41 @@ omapi_connection_wait(omapi_object_t *object,
|
||||
/*
|
||||
* This routine is not valid for server connections.
|
||||
*/
|
||||
REQUIRE(connection->is_client);
|
||||
INSIST(connection->is_client);
|
||||
|
||||
result = isc_mutex_lock(&connection->mutex);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) == ISC_R_SUCCESS);
|
||||
INSIST(connection->state == omapi_connection_connected);
|
||||
|
||||
connection->waiting = ISC_TRUE;
|
||||
|
||||
wait_result = ISC_R_SUCCESS;
|
||||
|
||||
while (connection->messages_expected > 0 &&
|
||||
wait_result == ISC_R_SUCCESS)
|
||||
while (connection->messages_expected > 0 && result == ISC_R_SUCCESS)
|
||||
|
||||
if (timeout == NULL)
|
||||
wait_result = isc_condition_wait(&connection->waiter,
|
||||
&connection->mutex);
|
||||
result = isc_condition_wait(&connection->waiter,
|
||||
&connection->mutex);
|
||||
else
|
||||
wait_result =
|
||||
isc_condition_waituntil(&connection->waiter,
|
||||
&connection->mutex,
|
||||
timeout);
|
||||
result = isc_condition_waituntil(&connection->waiter,
|
||||
&connection->mutex,
|
||||
timeout);
|
||||
|
||||
RUNTIME_CHECK(wait_result == ISC_R_SUCCESS ||
|
||||
wait_result == ISC_R_TIMEDOUT);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS || result == ISC_R_TIMEDOUT);
|
||||
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) == ISC_R_SUCCESS);
|
||||
connection->waiting = ISC_FALSE;
|
||||
|
||||
return (wait_result);
|
||||
}
|
||||
if (connection->state == omapi_connection_closed)
|
||||
/*
|
||||
* An error occurred and end_connection needs to have
|
||||
* free_connection called now that we're done looking
|
||||
* at connection->messages_expected.
|
||||
*
|
||||
* XXXDCL something better to do with the result value?
|
||||
*/
|
||||
free_connection(connection);
|
||||
else
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
|
||||
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);
|
||||
|
||||
PASS_SETVALUE(connection);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
PASS_GETVALUE(connection);
|
||||
}
|
||||
|
||||
void
|
||||
omapi_connection_destroy(omapi_object_t *handle, const char *name) {
|
||||
omapi_connection_object_t *connection;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_connection_signalhandler(omapi_object_t *connection, const char *name,
|
||||
va_list ap)
|
||||
{
|
||||
REQUIRE(connection != NULL &&
|
||||
connection->type == omapi_type_connection);
|
||||
|
||||
PASS_SIGNAL(connection);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write all the published values associated with the object through the
|
||||
* specified connection.
|
||||
*/
|
||||
isc_result_t
|
||||
omapi_connection_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
|
||||
omapi_object_t *handle)
|
||||
{
|
||||
REQUIRE(connection != NULL &&
|
||||
connection->type == omapi_type_connection);
|
||||
|
||||
PASS_STUFFVALUES(handle);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1163,3 +1183,71 @@ omapi_connection_puthandle(omapi_object_t *c, omapi_object_t *h) {
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
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);
|
||||
|
||||
PASS_SETVALUE(connection);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
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);
|
||||
|
||||
PASS_GETVALUE(connection);
|
||||
}
|
||||
|
||||
static void
|
||||
connection_destroy(omapi_object_t *handle) {
|
||||
omapi_connection_object_t *connection;
|
||||
|
||||
REQUIRE(handle != NULL && handle->type == omapi_type_connection);
|
||||
|
||||
connection = (omapi_connection_object_t *)handle;
|
||||
|
||||
if (connection->state == omapi_connection_connected)
|
||||
omapi_connection_disconnect(handle, OMAPI_FORCE_DISCONNECT);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
connection_signalhandler(omapi_object_t *connection, const char *name,
|
||||
va_list ap)
|
||||
{
|
||||
REQUIRE(connection != NULL &&
|
||||
connection->type == omapi_type_connection);
|
||||
|
||||
PASS_SIGNAL(connection);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write all the published values associated with the object through the
|
||||
* specified connection.
|
||||
*/
|
||||
static isc_result_t
|
||||
connection_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
|
||||
omapi_object_t *handle)
|
||||
{
|
||||
REQUIRE(connection != NULL &&
|
||||
connection->type == omapi_type_connection);
|
||||
|
||||
PASS_STUFFVALUES(handle);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_connection_init(void) {
|
||||
return (omapi_object_register(&omapi_type_connection,
|
||||
"connection",
|
||||
connection_setvalue,
|
||||
connection_getvalue,
|
||||
connection_destroy,
|
||||
connection_signalhandler,
|
||||
connection_stuffvalues,
|
||||
NULL, NULL, NULL));
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: data.c,v 1.2 2000/01/13 06:13:21 tale Exp $ */
|
||||
/* $Id: data.c,v 1.3 2000/01/17 18:02:05 tale Exp $ */
|
||||
|
||||
/* Principal Author: Ted Lemon */
|
||||
|
||||
@ -93,8 +93,7 @@ omapi_data_new(omapi_typed_data_t **t, omapi_datatype_t type, ...) {
|
||||
new->u.buffer.len = val;
|
||||
break;
|
||||
case omapi_datatype_object:
|
||||
OBJECT_REF(&new->u.object, va_arg(l, omapi_object_t *),
|
||||
"omapi_datatype_new");
|
||||
OBJECT_REF(&new->u.object, va_arg(l, omapi_object_t *));
|
||||
break;
|
||||
}
|
||||
new->type = type;
|
||||
@ -117,7 +116,7 @@ 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) {
|
||||
omapi_data_dereference(omapi_typed_data_t **h) {
|
||||
int length = 0;
|
||||
|
||||
|
||||
@ -138,7 +137,7 @@ omapi_data_dereference(omapi_typed_data_t **h, const char *name) {
|
||||
(*h)->u.buffer.len;
|
||||
break;
|
||||
case omapi_datatype_object:
|
||||
OBJECT_DEREF(&(*h)->u.object, name);
|
||||
OBJECT_DEREF(&(*h)->u.object);
|
||||
length = OMAPI_TYPED_DATA_OBJECT_LEN;
|
||||
break;
|
||||
default:
|
||||
@ -237,7 +236,7 @@ omapi_data_valuedereference(omapi_value_t **h, const char *name) {
|
||||
if ((*h)->name != NULL)
|
||||
omapi_data_stringdereference(&(*h)->name, name);
|
||||
if ((*h)->value != NULL)
|
||||
omapi_data_dereference(&(*h)->value, name);
|
||||
omapi_data_dereference(&(*h)->value);
|
||||
isc_mem_put(omapi_mctx, *h, sizeof(*h));
|
||||
}
|
||||
*h = NULL;
|
||||
|
@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: dispatch.c,v 1.7 2000/01/13 06:13:22 tale Exp $ */
|
||||
/* $Id: dispatch.c,v 1.8 2000/01/17 18:02:05 tale Exp $ */
|
||||
|
||||
/* Principal Author: Ted Lemon */
|
||||
|
||||
@ -39,64 +39,3 @@ omapi_dispatch(struct timeval *t) {
|
||||
select(0, NULL, NULL, NULL, t ? t : NULL);
|
||||
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)
|
||||
{
|
||||
REQUIRE(io != NULL && io->type == omapi_type_io_object);
|
||||
|
||||
PASS_SETVALUE(io);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_io_getvalue(omapi_object_t *io, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_value_t **value)
|
||||
{
|
||||
REQUIRE(io != NULL && io->type == omapi_type_io_object);
|
||||
|
||||
PASS_GETVALUE(io);
|
||||
}
|
||||
|
||||
void
|
||||
omapi_io_destroy(omapi_object_t *io, const char *name) {
|
||||
REQUIRE(io != NULL && io->type == omapi_type_io_object);
|
||||
|
||||
(void)name; /* Unused. */
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_io_signalhandler(omapi_object_t *io, const char *name, va_list ap)
|
||||
{
|
||||
REQUIRE(io != NULL && io->type == omapi_type_io_object);
|
||||
|
||||
PASS_SIGNAL(io);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_io_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
|
||||
omapi_object_t *io)
|
||||
{
|
||||
REQUIRE(io != NULL && io->type == omapi_type_io_object);
|
||||
|
||||
PASS_STUFFVALUES(io);
|
||||
}
|
||||
|
||||
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;
|
||||
isc_condition_signal(&waiter->ready);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
PASS_SIGNAL(h);
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: generic.c,v 1.6 2000/01/13 06:13:22 tale Exp $ */
|
||||
/* $Id: generic.c,v 1.7 2000/01/17 18:02:06 tale Exp $ */
|
||||
|
||||
/* Principal Author: Ted Lemon */
|
||||
|
||||
@ -29,9 +29,10 @@
|
||||
|
||||
#include <omapi/private.h>
|
||||
|
||||
#if 0
|
||||
isc_result_t
|
||||
omapi_generic_new(omapi_object_t **gen, const char *name) {
|
||||
omapi_generic_object_t *obj;
|
||||
omapi_generic_new(omapi_object_t **generic_handle, const char *name) {
|
||||
omapi_generic_object_t *generic;
|
||||
|
||||
obj = isc_mem_get(omapi_mctx, sizeof(*obj));
|
||||
if (obj == NULL)
|
||||
@ -40,14 +41,15 @@ omapi_generic_new(omapi_object_t **gen, const char *name) {
|
||||
obj->refcnt = 0;
|
||||
obj->type = omapi_type_generic;
|
||||
|
||||
OBJECT_REF(gen, obj, name);
|
||||
OBJECT_REF(gen, obj);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
|
||||
isc_result_t
|
||||
omapi_generic_set_value(omapi_object_t *h, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_typed_data_t *value)
|
||||
static isc_result_t
|
||||
generic_setvalue(omapi_object_t *h, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_typed_data_t *value)
|
||||
{
|
||||
omapi_generic_object_t *g;
|
||||
omapi_value_t *new;
|
||||
@ -161,9 +163,9 @@ omapi_generic_set_value(omapi_object_t *h, omapi_object_t *id,
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_generic_get_value(omapi_object_t *h, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_value_t **value)
|
||||
static isc_result_t
|
||||
generic_getvalue(omapi_object_t *h, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_value_t **value)
|
||||
{
|
||||
unsigned int i;
|
||||
omapi_generic_object_t *g;
|
||||
@ -196,8 +198,8 @@ omapi_generic_get_value(omapi_object_t *h, omapi_object_t *id,
|
||||
PASS_GETVALUE(h);
|
||||
}
|
||||
|
||||
void
|
||||
omapi_generic_destroy(omapi_object_t *h, const char *name) {
|
||||
static void
|
||||
generic_destroy(omapi_object_t *h) {
|
||||
omapi_generic_object_t *g;
|
||||
unsigned int i;
|
||||
|
||||
@ -209,7 +211,7 @@ omapi_generic_destroy(omapi_object_t *h, const char *name) {
|
||||
for (i = 0; i < g->nvalues; i++)
|
||||
if (g->values[i] != NULL)
|
||||
omapi_data_valuedereference(&g->values[i],
|
||||
name);
|
||||
NULL);
|
||||
|
||||
isc_mem_put(omapi_mctx, g->values,
|
||||
g->va_max * sizeof(*g->values));
|
||||
@ -218,8 +220,8 @@ omapi_generic_destroy(omapi_object_t *h, const char *name) {
|
||||
}
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_generic_signal_handler(omapi_object_t *h, const char *name, va_list ap) {
|
||||
static isc_result_t
|
||||
generic_signalhandler(omapi_object_t *h, const char *name, va_list ap) {
|
||||
|
||||
REQUIRE(h != NULL && h->type == omapi_type_generic);
|
||||
|
||||
@ -230,10 +232,9 @@ omapi_generic_signal_handler(omapi_object_t *h, const char *name, va_list ap) {
|
||||
* Write all the published values associated with the object through the
|
||||
* specified connection.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
omapi_generic_stuff_values(omapi_object_t *connection, omapi_object_t *id,
|
||||
omapi_object_t *h)
|
||||
static isc_result_t
|
||||
generic_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
|
||||
omapi_object_t *h)
|
||||
{
|
||||
omapi_generic_object_t *src;
|
||||
unsigned int i;
|
||||
@ -265,3 +266,15 @@ omapi_generic_stuff_values(omapi_object_t *connection, omapi_object_t *id,
|
||||
|
||||
PASS_STUFFVALUES(h);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_generic_init(void) {
|
||||
return (omapi_object_register(&omapi_type_generic,
|
||||
"generic",
|
||||
generic_setvalue,
|
||||
generic_getvalue,
|
||||
generic_destroy,
|
||||
generic_signalhandler,
|
||||
generic_stuffvalues,
|
||||
NULL, NULL, NULL));
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: handle.c,v 1.4 2000/01/13 06:13:23 tale Exp $ */
|
||||
/* $Id: handle.c,v 1.5 2000/01/17 18:02:06 tale Exp $ */
|
||||
|
||||
/* Principal Author: Ted Lemon */
|
||||
|
||||
@ -176,8 +176,7 @@ omapi_object_handle_in_table(omapi_handle_t h, omapi_handle_table_t *table,
|
||||
* appropriate place.
|
||||
*/
|
||||
if (table->leaf) {
|
||||
OBJECT_REF(&table->children[h - table->first].object, o,
|
||||
"omapi_object_handle_in_table");
|
||||
OBJECT_REF(&table->children[h - table->first].object, o);
|
||||
o->handle = h;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
@ -296,8 +295,7 @@ omapi_handle_lookup_in(omapi_object_t **o, omapi_handle_t h,
|
||||
if (table->children[h - table->first].object == NULL)
|
||||
return (ISC_R_NOTFOUND);
|
||||
|
||||
OBJECT_REF(o, table->children[h - table->first].object,
|
||||
"omapi_handle_lookup_in");
|
||||
OBJECT_REF(o, table->children[h - table->first].object);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,11 @@ typedef struct omapi_typed_data omapi_typed_data_t;
|
||||
typedef struct omapi_data_string omapi_data_string_t;
|
||||
typedef struct omapi_value omapi_value_t;
|
||||
|
||||
/*
|
||||
* This preamble is common to all objects manipulated by libomapi.a,
|
||||
* including specials objects created by external users of the library.
|
||||
* It needs to be at the start of every struct that gets used as an object.
|
||||
*/
|
||||
#define OMAPI_OBJECT_PREAMBLE \
|
||||
omapi_object_type_t * type; \
|
||||
size_t object_size; \
|
||||
@ -168,25 +173,11 @@ struct omapi_object_type {
|
||||
|
||||
/*
|
||||
* For use with omapi_connection_disconnect().
|
||||
* XXXDCL rename
|
||||
*/
|
||||
#define OMAPI_FORCE_DISCONNECT ISC_TRUE
|
||||
#define OMAPI_CLEAN_DISCONNECT ISC_FALSE
|
||||
|
||||
/*****
|
||||
***** Global Variables.
|
||||
*****/
|
||||
extern omapi_object_type_t *omapi_type_connection;
|
||||
extern omapi_object_type_t *omapi_type_listener;
|
||||
extern omapi_object_type_t *omapi_type_io_object;
|
||||
extern omapi_object_type_t *omapi_type_generic;
|
||||
extern omapi_object_type_t *omapi_type_protocol;
|
||||
extern omapi_object_type_t *omapi_type_protocol_listener;
|
||||
extern omapi_object_type_t *omapi_type_waiter;
|
||||
extern omapi_object_type_t *omapi_type_remote;
|
||||
extern omapi_object_type_t *omapi_type_message;
|
||||
|
||||
extern omapi_object_type_t *omapi_object_types;
|
||||
|
||||
/*****
|
||||
***** Function Prototypes.
|
||||
*****/
|
||||
@ -221,7 +212,7 @@ omapi_protocol_stuff_values(omapi_object_t *connection, omapi_object_t *id,
|
||||
omapi_object_t *object);
|
||||
|
||||
void
|
||||
omapi_protocol_destroy(omapi_object_t *object, const char *name);
|
||||
omapi_protocol_destroy(omapi_object_t *object);
|
||||
|
||||
isc_result_t
|
||||
omapi_protocol_send_message(omapi_object_t *protocol,
|
||||
@ -243,7 +234,7 @@ omapi_protocol_listener_get_value(omapi_object_t *object, omapi_object_t *id,
|
||||
omapi_value_t **value);
|
||||
|
||||
void
|
||||
omapi_protocol_listener_destroy(omapi_object_t *object, const char *name);
|
||||
omapi_protocol_listener_destroy(omapi_object_t *object);
|
||||
|
||||
isc_result_t
|
||||
omapi_protocol_listener_signal(omapi_object_t *protocol_listener,
|
||||
@ -275,49 +266,12 @@ omapi_connection_toserver(omapi_object_t *connection, const char *server,
|
||||
void
|
||||
omapi_connection_disconnect(omapi_object_t *connection, isc_boolean_t force);
|
||||
|
||||
int
|
||||
omapi_connection_readfd(omapi_object_t *connection);
|
||||
|
||||
int
|
||||
omapi_connection_writefd(omapi_object_t *connection);
|
||||
|
||||
void
|
||||
omapi_connection_read(isc_task_t *task, isc_event_t *event);
|
||||
|
||||
isc_result_t
|
||||
omapi_connection_reader(omapi_object_t *connection);
|
||||
|
||||
isc_result_t
|
||||
omapi_connection_writer(omapi_object_t *connection);
|
||||
|
||||
isc_result_t
|
||||
omapi_connection_reaper(omapi_object_t *connection);
|
||||
|
||||
isc_result_t
|
||||
omapi_connection_setvalue(omapi_object_t *connection, omapi_object_t *id,
|
||||
omapi_data_string_t *name,
|
||||
omapi_typed_data_t *value);
|
||||
|
||||
isc_result_t
|
||||
omapi_connection_getvalue(omapi_object_t *connection, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_value_t **value);
|
||||
|
||||
void
|
||||
omapi_connection_destroy(omapi_object_t *connection, const char *name);
|
||||
|
||||
isc_result_t
|
||||
omapi_connection_signalhandler(omapi_object_t *connection, const char *name,
|
||||
va_list args);
|
||||
|
||||
isc_result_t
|
||||
omapi_connection_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
|
||||
omapi_object_t *object);
|
||||
|
||||
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,
|
||||
omapi_connection_wait(omapi_object_t *object,
|
||||
omapi_object_t *connection_handle,
|
||||
isc_time_t *timeout);
|
||||
|
||||
isc_result_t
|
||||
@ -360,119 +314,22 @@ omapi_connection_puthandle(omapi_object_t *connection,
|
||||
isc_result_t
|
||||
omapi_listener_listen(omapi_object_t *listener, int port, int backlog);
|
||||
|
||||
isc_result_t
|
||||
omapi_listener_setvalue(omapi_object_t *listener, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_typed_data_t *value);
|
||||
|
||||
isc_result_t
|
||||
omapi_listener_getvalue(omapi_object_t *listener, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_value_t **value);
|
||||
|
||||
void
|
||||
omapi_listener_destroy(omapi_object_t *listener, const char *name);
|
||||
|
||||
isc_result_t
|
||||
omapi_listener_signalhandler(omapi_object_t *listener, const char *name,
|
||||
va_list args);
|
||||
|
||||
isc_result_t
|
||||
omapi_listener_stuffvalues(omapi_object_t *listener, omapi_object_t *id,
|
||||
omapi_object_t *object);
|
||||
|
||||
/*
|
||||
* dispatch.c
|
||||
*/
|
||||
isc_result_t
|
||||
omapi_register_io_object(omapi_object_t *object,
|
||||
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 *));
|
||||
|
||||
isc_result_t
|
||||
omapi_dispatch(struct timeval *timeout);
|
||||
|
||||
isc_result_t
|
||||
omapi_wait_for_completion(omapi_object_t *io, struct timeval *timeout);
|
||||
|
||||
isc_result_t
|
||||
omapi_one_dispatch(omapi_object_t *waiter, struct timeval *timeout);
|
||||
|
||||
isc_result_t
|
||||
omapi_io_setvalue(omapi_object_t *io, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_typed_data_t *value);
|
||||
|
||||
isc_result_t
|
||||
omapi_io_getvalue(omapi_object_t *io, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_value_t **value);
|
||||
|
||||
void
|
||||
omapi_io_destroy(omapi_object_t *io, const char *name);
|
||||
|
||||
isc_result_t
|
||||
omapi_io_signalhandler(omapi_object_t *io, const char *name, va_list args);
|
||||
|
||||
isc_result_t
|
||||
omapi_io_stuffvalues(omapi_object_t *io, omapi_object_t *id,
|
||||
omapi_object_t *object);
|
||||
isc_result_t
|
||||
omapi_waiter_signal_handler(omapi_object_t *waiter, const char *name,
|
||||
va_list args);
|
||||
|
||||
/*
|
||||
* generic.c
|
||||
*/
|
||||
isc_result_t
|
||||
omapi_generic_new(omapi_object_t **generic, const char *name);
|
||||
|
||||
isc_result_t
|
||||
omapi_generic_set_value(omapi_object_t *generic, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_typed_data_t *value);
|
||||
|
||||
isc_result_t
|
||||
omapi_generic_get_value(omapi_object_t *generic, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_value_t **value);
|
||||
|
||||
void
|
||||
omapi_generic_destroy(omapi_object_t *generic, const char *name);
|
||||
|
||||
isc_result_t
|
||||
omapi_generic_signal_handler(omapi_object_t *generic, const char *name,
|
||||
va_list args);
|
||||
|
||||
isc_result_t
|
||||
omapi_generic_stuff_values(omapi_object_t *generic, omapi_object_t *id,
|
||||
omapi_object_t *object);
|
||||
|
||||
/*
|
||||
* message.c
|
||||
*/
|
||||
isc_result_t
|
||||
omapi_message_new(omapi_object_t **message, const char *name);
|
||||
omapi_message_new(omapi_object_t **message);
|
||||
|
||||
isc_result_t
|
||||
omapi_message_setvalue(omapi_object_t *message, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_typed_data_t *value);
|
||||
isc_result_t
|
||||
omapi_message_getvalue(omapi_object_t *message, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_value_t **value);
|
||||
void
|
||||
omapi_message_destroy(omapi_object_t *message, const char *name);
|
||||
|
||||
isc_result_t
|
||||
omapi_message_signalhandler(omapi_object_t *message, const char *name,
|
||||
va_list args);
|
||||
|
||||
isc_result_t
|
||||
omapi_message_stuffvalues(omapi_object_t *message, omapi_object_t *id,
|
||||
omapi_object_t *object);
|
||||
isc_result_t
|
||||
omapi_message_register(omapi_object_t *message);
|
||||
|
||||
isc_result_t
|
||||
omapi_message_unregister(omapi_object_t *message);
|
||||
|
||||
isc_result_t
|
||||
omapi_message_process(omapi_object_t *message, omapi_object_t *protocol);
|
||||
|
||||
@ -483,47 +340,45 @@ isc_result_t
|
||||
omapi_init(isc_mem_t *mctx);
|
||||
|
||||
void
|
||||
omapi_shutdown(void);
|
||||
omapi_destroy(void);
|
||||
|
||||
isc_result_t
|
||||
omapi_object_type_register(omapi_object_type_t **type,
|
||||
const char *name,
|
||||
isc_result_t ((*set_value)
|
||||
omapi_object_register(omapi_object_type_t **type, const char *name,
|
||||
isc_result_t ((*set_value)
|
||||
(omapi_object_t *,
|
||||
omapi_object_t *,
|
||||
omapi_data_string_t *,
|
||||
omapi_typed_data_t *)),
|
||||
|
||||
isc_result_t ((*get_value)
|
||||
isc_result_t ((*get_value)
|
||||
(omapi_object_t *,
|
||||
omapi_object_t *,
|
||||
omapi_data_string_t *,
|
||||
omapi_value_t **)),
|
||||
|
||||
void ((*destroy)
|
||||
(omapi_object_t *,
|
||||
const char *)),
|
||||
void ((*destroy)
|
||||
(omapi_object_t *)),
|
||||
|
||||
isc_result_t ((*signal_handler)
|
||||
isc_result_t ((*signal_handler)
|
||||
(omapi_object_t *,
|
||||
const char *,
|
||||
va_list)),
|
||||
|
||||
isc_result_t ((*stuff_values)
|
||||
isc_result_t ((*stuff_values)
|
||||
(omapi_object_t *,
|
||||
omapi_object_t *,
|
||||
omapi_object_t *)),
|
||||
|
||||
isc_result_t ((*lookup)
|
||||
isc_result_t ((*lookup)
|
||||
(omapi_object_t **,
|
||||
omapi_object_t *,
|
||||
omapi_object_t *)),
|
||||
|
||||
isc_result_t ((*create)
|
||||
isc_result_t ((*create)
|
||||
(omapi_object_t **,
|
||||
omapi_object_t *)),
|
||||
|
||||
isc_result_t ((*remove)
|
||||
isc_result_t ((*remove)
|
||||
(omapi_object_t *,
|
||||
omapi_object_t *)));
|
||||
|
||||
@ -569,10 +424,6 @@ isc_result_t
|
||||
omapi_stuff_values(omapi_object_t *handle, omapi_object_t *id,
|
||||
omapi_object_t *object);
|
||||
|
||||
isc_result_t
|
||||
omapi_object_create(omapi_object_t **object, omapi_object_t *id,
|
||||
omapi_object_type_t *type);
|
||||
|
||||
isc_result_t
|
||||
omapi_object_update(omapi_object_t *object, omapi_object_t *id,
|
||||
omapi_object_t *source, omapi_handle_t handle);
|
||||
@ -627,15 +478,14 @@ omapi_handle_td_lookup(omapi_object_t **object, omapi_typed_data_t *data);
|
||||
* object.c
|
||||
*/
|
||||
isc_result_t
|
||||
omapi_object_new(omapi_object_t **object, omapi_object_type_t *type,
|
||||
omapi_object_create(omapi_object_t **object, omapi_object_type_t *type,
|
||||
size_t size);
|
||||
|
||||
void
|
||||
omapi_object_reference(omapi_object_t **reference, omapi_object_t *object,
|
||||
const char *name);
|
||||
omapi_object_reference(omapi_object_t **reference, omapi_object_t *object);
|
||||
|
||||
void
|
||||
omapi_object_dereference(omapi_object_t **reference, const char *name);
|
||||
omapi_object_dereference(omapi_object_t **reference);
|
||||
|
||||
/*
|
||||
* data.c
|
||||
@ -649,7 +499,7 @@ omapi_data_reference(omapi_typed_data_t **reference, omapi_typed_data_t *data,
|
||||
const char *name);
|
||||
|
||||
void
|
||||
omapi_data_dereference(omapi_typed_data_t **reference, const char *name);
|
||||
omapi_data_dereference(omapi_typed_data_t **reference);
|
||||
|
||||
isc_result_t
|
||||
omapi_data_newstring(omapi_data_string_t **string, unsigned int length,
|
||||
|
@ -70,10 +70,12 @@ typedef struct omapi_message_object {
|
||||
typedef struct omapi_connection_object {
|
||||
OMAPI_OBJECT_PREAMBLE;
|
||||
isc_mutex_t mutex;
|
||||
isc_mutex_t recv_lock;
|
||||
isc_socket_t *socket; /* Connection socket. */
|
||||
isc_task_t *task;
|
||||
unsigned int events_pending; /* socket events */
|
||||
unsigned int messages_expected;
|
||||
isc_boolean_t waiting;
|
||||
isc_condition_t waiter; /* omapi_connection_wait() */
|
||||
omapi_connection_state_t state;
|
||||
isc_sockaddr_t remote_addr;
|
||||
@ -96,23 +98,14 @@ 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;
|
||||
unsigned int nvalues;
|
||||
unsigned int va_max;
|
||||
omapi_value_t ** values;
|
||||
unsigned int nvalues;
|
||||
unsigned int va_max;
|
||||
} omapi_generic_object_t;
|
||||
|
||||
typedef struct omapi_waiter_object {
|
||||
@ -121,6 +114,18 @@ typedef struct omapi_waiter_object {
|
||||
isc_condition_t ready;
|
||||
} omapi_waiter_object_t;
|
||||
|
||||
/*****
|
||||
***** Global Variables.
|
||||
*****/
|
||||
extern omapi_object_type_t *omapi_type_connection;
|
||||
extern omapi_object_type_t *omapi_type_listener;
|
||||
extern omapi_object_type_t *omapi_type_generic;
|
||||
extern omapi_object_type_t *omapi_type_protocol;
|
||||
extern omapi_object_type_t *omapi_type_protocol_listener;
|
||||
extern omapi_object_type_t *omapi_type_message;
|
||||
|
||||
extern omapi_object_type_t *omapi_object_types;
|
||||
|
||||
/*
|
||||
* Everything needs a memory context. This will likely be made a parameter
|
||||
* where needed rather than a single global context. XXXDCL
|
||||
@ -132,11 +137,6 @@ extern isc_mem_t *omapi_mctx;
|
||||
*/
|
||||
extern isc_taskmgr_t *omapi_taskmgr;
|
||||
|
||||
/*
|
||||
* XXXDCL comment, localize?
|
||||
*/
|
||||
extern isc_timermgr_t *omapi_timermgr;
|
||||
|
||||
/*
|
||||
* XXXDCL comment, localize?
|
||||
*/
|
||||
@ -147,12 +147,12 @@ extern isc_boolean_t omapi_ipv6;
|
||||
void
|
||||
connection_send(omapi_connection_object_t *connection);
|
||||
|
||||
#define OBJECT_REF(objectp, object, where) \
|
||||
#define OBJECT_REF(objectp, object) \
|
||||
omapi_object_reference((omapi_object_t **)objectp, \
|
||||
(omapi_object_t *)object, where)
|
||||
(omapi_object_t *)object)
|
||||
|
||||
#define OBJECT_DEREF(objectp, where) \
|
||||
omapi_object_dereference((omapi_object_t **)objectp, where)
|
||||
#define OBJECT_DEREF(objectp) \
|
||||
omapi_object_dereference((omapi_object_t **)objectp)
|
||||
|
||||
#define PASS_CHECK(object, function) \
|
||||
(object->inner != NULL && object->inner->type->function != NULL)
|
||||
@ -193,6 +193,18 @@ connection_send(omapi_connection_object_t *connection);
|
||||
return (ISC_R_SUCCESS); \
|
||||
} while (0)
|
||||
|
||||
isc_result_t
|
||||
omapi_connection_init(void);
|
||||
|
||||
isc_result_t
|
||||
omapi_listener_init(void);
|
||||
|
||||
isc_result_t
|
||||
omapi_generic_init(void);
|
||||
|
||||
isc_result_t
|
||||
omapi_message_init(void);
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* OMAPIP_OMAPIP_P_H */
|
||||
|
@ -40,7 +40,7 @@ typedef struct omapi_listener_object {
|
||||
* Reader callback for a listener object. Accept an incoming connection.
|
||||
*/
|
||||
static void
|
||||
omapi_listener_accept(isc_task_t *task, isc_event_t *event) {
|
||||
listener_accept(isc_task_t *task, isc_event_t *event) {
|
||||
isc_result_t result;
|
||||
isc_buffer_t *ibuffer, *obuffer;
|
||||
isc_task_t *connection_task = NULL;
|
||||
@ -58,7 +58,7 @@ omapi_listener_accept(isc_task_t *task, isc_event_t *event) {
|
||||
/*
|
||||
* Set up another listen task for the socket.
|
||||
*/
|
||||
isc_socket_accept(event->sender, task, omapi_listener_accept,
|
||||
isc_socket_accept(event->sender, task, listener_accept,
|
||||
event->arg);
|
||||
|
||||
/*
|
||||
@ -95,7 +95,7 @@ omapi_listener_accept(isc_task_t *task, isc_event_t *event) {
|
||||
/*
|
||||
* Create a new connection object.
|
||||
*/
|
||||
result = omapi_object_new((omapi_object_t **)&connection,
|
||||
result = omapi_object_create((omapi_object_t **)&connection,
|
||||
omapi_type_connection, sizeof(*connection));
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto free_obuffer;
|
||||
@ -118,6 +118,7 @@ omapi_listener_accept(isc_task_t *task, isc_event_t *event) {
|
||||
ISC_LIST_APPEND(connection->output_buffers, obuffer, link);
|
||||
|
||||
RUNTIME_CHECK(isc_mutex_init(&connection->mutex) == ISC_R_SUCCESS);
|
||||
RUNTIME_CHECK(isc_mutex_init(&connection->recv_lock) == ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Notify the listener object that a connection was made.
|
||||
@ -131,7 +132,7 @@ omapi_listener_accept(isc_task_t *task, isc_event_t *event) {
|
||||
* reaped. The omapi_protocol_listener_signal function added a
|
||||
* reference when it created a protocol object as connection->inner.
|
||||
*/
|
||||
OBJECT_DEREF(&connection, "omapi_listener_accept");
|
||||
OBJECT_DEREF(&connection);
|
||||
return;
|
||||
|
||||
free_object:
|
||||
@ -139,7 +140,7 @@ free_object:
|
||||
* Destroy the connection. This will free everything created
|
||||
* in this function but the event.
|
||||
*/
|
||||
OBJECT_DEREF(&connection, "omapi_listener_accept");
|
||||
OBJECT_DEREF(&connection);
|
||||
return;
|
||||
|
||||
/*
|
||||
@ -189,8 +190,8 @@ omapi_listener_listen(omapi_object_t *caller, int port, int max) {
|
||||
/*
|
||||
* Tie the listener object to the calling object.
|
||||
*/
|
||||
OBJECT_REF(&caller->outer, listener, "omapi_protocol_listen");
|
||||
OBJECT_REF(&listener->inner, caller, "omapi_protocol_listen");
|
||||
OBJECT_REF(&caller->outer, listener);
|
||||
OBJECT_REF(&listener->inner, caller);
|
||||
|
||||
/*
|
||||
* Create a socket on which to listen.
|
||||
@ -203,7 +204,7 @@ omapi_listener_listen(omapi_object_t *caller, int port, int max) {
|
||||
* because it has two refcnts, one for existing plus one
|
||||
* for the tie to h->outer. This does not seem right to me.
|
||||
*/
|
||||
OBJECT_DEREF(&listener, "omapi_listen");
|
||||
OBJECT_DEREF(&listener);
|
||||
return (result);
|
||||
}
|
||||
|
||||
@ -219,7 +220,7 @@ omapi_listener_listen(omapi_object_t *caller, int port, int max) {
|
||||
*/
|
||||
result = isc_socket_bind(listener->socket, &listener->address);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
OBJECT_DEREF(&listener, "omapi_listen");
|
||||
OBJECT_DEREF(&listener);
|
||||
return (result);
|
||||
}
|
||||
|
||||
@ -228,24 +229,24 @@ omapi_listener_listen(omapi_object_t *caller, int port, int max) {
|
||||
*/
|
||||
result = isc_socket_listen(listener->socket, max);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
OBJECT_DEREF(&listener, "omapi_listen");
|
||||
OBJECT_DEREF(&listener);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue up the first accept event. The listener object
|
||||
* will be passed to omapi_listener_accept() when it is called.
|
||||
* will be passed to listener_accept() when it is called.
|
||||
*/
|
||||
result = isc_socket_accept(listener->socket, task,
|
||||
omapi_listener_accept, listener);
|
||||
listener_accept, listener);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
OBJECT_DEREF(&listener, "omapi_listen");
|
||||
OBJECT_DEREF(&listener);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_listener_setvalue(omapi_object_t *listener, omapi_object_t *id,
|
||||
static isc_result_t
|
||||
listener_setvalue(omapi_object_t *listener, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_typed_data_t *value)
|
||||
{
|
||||
/*
|
||||
@ -257,8 +258,8 @@ omapi_listener_setvalue(omapi_object_t *listener, omapi_object_t *id,
|
||||
PASS_SETVALUE(listener);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_listener_getvalue(omapi_object_t *listener, omapi_object_t *id,
|
||||
static isc_result_t
|
||||
listener_getvalue(omapi_object_t *listener, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_value_t **value)
|
||||
{
|
||||
/*
|
||||
@ -270,14 +271,12 @@ omapi_listener_getvalue(omapi_object_t *listener, omapi_object_t *id,
|
||||
PASS_GETVALUE(listener);
|
||||
}
|
||||
|
||||
void
|
||||
omapi_listener_destroy(omapi_object_t *object, const char *name) {
|
||||
static void
|
||||
listener_destroy(omapi_object_t *object) {
|
||||
omapi_listener_object_t *listener;
|
||||
|
||||
REQUIRE(object != NULL && object->type == omapi_type_listener);
|
||||
|
||||
(void)name; /* Unused. */
|
||||
|
||||
listener = (omapi_listener_object_t *)object;
|
||||
|
||||
if (listener->socket != NULL) {
|
||||
@ -291,14 +290,13 @@ omapi_listener_destroy(omapi_object_t *object, const char *name) {
|
||||
}
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_listener_signalhandler(omapi_object_t *listener, const char *name,
|
||||
va_list ap)
|
||||
static isc_result_t
|
||||
listener_signalhandler(omapi_object_t *listener, const char *name, va_list ap)
|
||||
{
|
||||
REQUIRE(listener != NULL && listener->type == omapi_type_listener);
|
||||
|
||||
/*
|
||||
* This function is reached when omapi_listener_accept does
|
||||
* This function is reached when listener_accept does
|
||||
* an omapi_signal of "connect" on the listener object. Nothing
|
||||
* need be done here, but the object that originally requested
|
||||
* the listen needs to signalled that a connection was made.
|
||||
@ -314,12 +312,23 @@ omapi_listener_signalhandler(omapi_object_t *listener, const char *name,
|
||||
* Write all the published values associated with the object through the
|
||||
* specified connection.
|
||||
*/
|
||||
isc_result_t
|
||||
omapi_listener_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
|
||||
omapi_object_t *listener)
|
||||
static isc_result_t
|
||||
listener_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
|
||||
omapi_object_t *listener)
|
||||
{
|
||||
REQUIRE(listener != NULL && listener->type == omapi_type_listener);
|
||||
|
||||
PASS_STUFFVALUES(listener);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_listener_init(void) {
|
||||
return (omapi_object_register(&omapi_type_listener,
|
||||
"listener",
|
||||
listener_setvalue,
|
||||
listener_getvalue,
|
||||
listener_destroy,
|
||||
listener_signalhandler,
|
||||
listener_stuffvalues,
|
||||
NULL, NULL, NULL));
|
||||
}
|
||||
|
@ -28,236 +28,34 @@
|
||||
omapi_message_object_t *omapi_registered_messages;
|
||||
|
||||
isc_result_t
|
||||
omapi_message_new(omapi_object_t **o, const char *name) {
|
||||
omapi_message_new(omapi_object_t **o) {
|
||||
omapi_message_object_t *message = NULL;
|
||||
omapi_object_t *g;
|
||||
isc_result_t result;
|
||||
|
||||
result = omapi_object_new((omapi_object_t **)&message,
|
||||
omapi_type_message, sizeof(*message));
|
||||
result = omapi_object_create((omapi_object_t **)&message,
|
||||
omapi_type_message, sizeof(*message));
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
g = NULL;
|
||||
result = omapi_generic_new(&g, name);
|
||||
result = omapi_object_create(&g, NULL, 0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
OBJECT_DEREF(&message, "omapi_message_new");
|
||||
OBJECT_DEREF(&message);
|
||||
return (result);
|
||||
}
|
||||
|
||||
OBJECT_REF(&message->inner, g, name);
|
||||
OBJECT_REF(&g->outer, message, name);
|
||||
OBJECT_REF(o, message, name);
|
||||
OBJECT_REF(&message->inner, g);
|
||||
OBJECT_REF(&g->outer, message);
|
||||
OBJECT_REF(o, message);
|
||||
|
||||
OBJECT_DEREF(&message, name);
|
||||
OBJECT_DEREF(&g, name);
|
||||
OBJECT_DEREF(&message);
|
||||
OBJECT_DEREF(&g);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_message_setvalue(omapi_object_t *h, omapi_object_t *id,
|
||||
omapi_data_string_t *name,
|
||||
omapi_typed_data_t *value)
|
||||
{
|
||||
omapi_message_object_t *m;
|
||||
|
||||
REQUIRE(h != NULL && h->type == omapi_type_message);
|
||||
|
||||
m = (omapi_message_object_t *)h;
|
||||
|
||||
/*
|
||||
* Can't set authlen.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Can set authenticator, but the value must be typed data.
|
||||
*/
|
||||
if (omapi_ds_strcmp(name, "authenticator") == 0) {
|
||||
if (m->authenticator != NULL)
|
||||
omapi_data_dereference(&m->authenticator,
|
||||
"omapi_message_set_value");
|
||||
omapi_data_reference(&m->authenticator, value,
|
||||
"omapi_message_set_value");
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
} else if (omapi_ds_strcmp(name, "object") == 0) {
|
||||
INSIST(value != NULL && value->type == omapi_datatype_object);
|
||||
|
||||
if (m->object != NULL)
|
||||
OBJECT_DEREF(&m->object, "omapi_message_set_value");
|
||||
OBJECT_REF(&m->object, value->u.object,
|
||||
"omapi_message_set_value");
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
} else if (omapi_ds_strcmp(name, "notify-object") == 0) {
|
||||
INSIST(value != NULL && value->type == omapi_datatype_object);
|
||||
|
||||
if (m->notify_object != NULL)
|
||||
OBJECT_DEREF(&m->notify_object,
|
||||
"omapi_message_set_value");
|
||||
OBJECT_REF(&m->notify_object, value->u.object,
|
||||
"omapi_message_set_value");
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Can set authid, but it has to be an integer.
|
||||
*/
|
||||
} else if (omapi_ds_strcmp(name, "authid") == 0) {
|
||||
INSIST(value != NULL && value->type == omapi_datatype_int);
|
||||
|
||||
m->authid = value->u.integer;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Can set op, but it has to be an integer.
|
||||
*/
|
||||
} else if (omapi_ds_strcmp(name, "op") == 0) {
|
||||
INSIST(value != NULL && value->type == omapi_datatype_int);
|
||||
|
||||
m->op = value->u.integer;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Handle also has to be an integer.
|
||||
*/
|
||||
} else if (omapi_ds_strcmp(name, "handle") == 0) {
|
||||
INSIST(value != NULL && value->type == omapi_datatype_int);
|
||||
|
||||
m->h = value->u.integer;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Transaction ID has to be an integer.
|
||||
*/
|
||||
} else if (omapi_ds_strcmp(name, "id") == 0) {
|
||||
INSIST(value != NULL && value->type == omapi_datatype_int);
|
||||
|
||||
m->id = value->u.integer;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Remote transaction ID has to be an integer.
|
||||
*/
|
||||
} else if (omapi_ds_strcmp(name, "rid") == 0) {
|
||||
INSIST(value != NULL && value->type == omapi_datatype_int);
|
||||
|
||||
m->rid = value->u.integer;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to find some inner object that can take the value.
|
||||
*/
|
||||
PASS_SETVALUE(h);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_message_getvalue(omapi_object_t *h, omapi_object_t *id,
|
||||
omapi_data_string_t *name,
|
||||
omapi_value_t **value)
|
||||
{
|
||||
omapi_message_object_t *m;
|
||||
|
||||
REQUIRE(h != NULL && h->type == omapi_type_message);
|
||||
|
||||
m = (omapi_message_object_t *)h;
|
||||
|
||||
/*
|
||||
* Look for values that are in the message data structure.
|
||||
*/
|
||||
if (omapi_ds_strcmp(name, "authlen") == 0)
|
||||
return (omapi_make_int_value(value, name, (int)m->authlen,
|
||||
"omapi_message_get_value"));
|
||||
else if (omapi_ds_strcmp(name, "authenticator") == 0) {
|
||||
if (m->authenticator != NULL)
|
||||
return (omapi_make_value(value, name, m->authenticator,
|
||||
"omapi_message_get_value"));
|
||||
else
|
||||
return (ISC_R_NOTFOUND);
|
||||
} else if (omapi_ds_strcmp(name, "authid") == 0) {
|
||||
return (omapi_make_int_value(value, name, (int)m->authid,
|
||||
"omapi_message_get_value"));
|
||||
} else if (omapi_ds_strcmp(name, "op") == 0) {
|
||||
return (omapi_make_int_value(value, name, (int)m->op,
|
||||
"omapi_message_get_value"));
|
||||
} else if (omapi_ds_strcmp(name, "handle") == 0) {
|
||||
return (omapi_make_int_value(value, name, (int)m->handle,
|
||||
"omapi_message_get_value"));
|
||||
} else if (omapi_ds_strcmp(name, "id") == 0) {
|
||||
return (omapi_make_int_value(value, name, (int)m->id,
|
||||
"omapi_message_get_value"));
|
||||
} else if (omapi_ds_strcmp(name, "rid") == 0) {
|
||||
return (omapi_make_int_value(value, name, (int)m->rid,
|
||||
"omapi_message_get_value"));
|
||||
}
|
||||
|
||||
/*
|
||||
* See if there's an inner object that has the value.
|
||||
*/
|
||||
PASS_GETVALUE(h);
|
||||
}
|
||||
|
||||
void
|
||||
omapi_message_destroy(omapi_object_t *handle, const char *name) {
|
||||
omapi_message_object_t *message;
|
||||
|
||||
REQUIRE(handle != NULL && handle->type == omapi_type_message);
|
||||
|
||||
message = (omapi_message_object_t *)handle;
|
||||
|
||||
if (message->authenticator != NULL)
|
||||
omapi_data_dereference(&message->authenticator, name);
|
||||
|
||||
if (message->prev == NULL && omapi_registered_messages != message)
|
||||
omapi_message_unregister(handle);
|
||||
if (message->prev != NULL)
|
||||
OBJECT_DEREF(&message->prev, name);
|
||||
if (message->next != NULL)
|
||||
OBJECT_DEREF(&message->next, name);
|
||||
if (message->id_object != NULL)
|
||||
OBJECT_DEREF(&message->id_object, name);
|
||||
if (message->object != NULL)
|
||||
OBJECT_DEREF(&message->object, name);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_message_signalhandler(omapi_object_t *handle, const char *name,
|
||||
va_list ap) {
|
||||
omapi_message_object_t *message;
|
||||
|
||||
REQUIRE(handle != NULL && handle->type == omapi_type_message);
|
||||
|
||||
message = (omapi_message_object_t *)handle;
|
||||
|
||||
if (strcmp(name, "status") == 0 &&
|
||||
(message->object != NULL || message->notify_object != NULL)) {
|
||||
if (message->object != NULL)
|
||||
return ((message->object->type->signal_handler))
|
||||
(message->object, name, ap);
|
||||
else
|
||||
return ((message->notify_object->type->signal_handler))
|
||||
(message->notify_object, name, ap);
|
||||
}
|
||||
|
||||
PASS_SIGNAL(handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write all the published values associated with the object through the
|
||||
* specified connection.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
omapi_message_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
|
||||
omapi_object_t *message)
|
||||
{
|
||||
REQUIRE(message != NULL && message->type == omapi_type_message);
|
||||
|
||||
PASS_STUFFVALUES(message);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_message_register(omapi_object_t *h) {
|
||||
omapi_message_object_t *m;
|
||||
|
||||
@ -272,20 +70,15 @@ omapi_message_register(omapi_object_t *h) {
|
||||
omapi_registered_messages != m);
|
||||
|
||||
if (omapi_registered_messages != NULL) {
|
||||
OBJECT_REF(&m->next, omapi_registered_messages,
|
||||
"omapi_message_register");
|
||||
OBJECT_REF(&omapi_registered_messages->prev, m,
|
||||
"omapi_message_register");
|
||||
OBJECT_DEREF(&omapi_registered_messages,
|
||||
"omapi_message_register");
|
||||
OBJECT_REF(&m->next, omapi_registered_messages);
|
||||
OBJECT_REF(&omapi_registered_messages->prev, m);
|
||||
OBJECT_DEREF(&omapi_registered_messages);
|
||||
}
|
||||
|
||||
OBJECT_REF(&omapi_registered_messages, m,
|
||||
"omapi_message_register");
|
||||
return (ISC_R_SUCCESS);
|
||||
OBJECT_REF(&omapi_registered_messages, m);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
static void
|
||||
omapi_message_unregister(omapi_object_t *h) {
|
||||
omapi_message_object_t *m;
|
||||
omapi_message_object_t *n;
|
||||
@ -301,35 +94,31 @@ omapi_message_unregister(omapi_object_t *h) {
|
||||
|
||||
n = NULL;
|
||||
if (m->next != NULL) {
|
||||
OBJECT_REF(&n, m->next, "omapi_message_unregister");
|
||||
OBJECT_DEREF(&m->next, "omapi_message_unregister");
|
||||
OBJECT_REF(&n, m->next);
|
||||
OBJECT_DEREF(&m->next);
|
||||
}
|
||||
|
||||
if (m->prev != NULL) {
|
||||
omapi_message_object_t *tmp = NULL;
|
||||
OBJECT_REF(&tmp, m->prev, "omapi_message_register");
|
||||
OBJECT_DEREF(&m->prev, "omapi_message_unregister");
|
||||
OBJECT_REF(&tmp, m->prev);
|
||||
OBJECT_DEREF(&m->prev);
|
||||
|
||||
if (tmp->next != NULL)
|
||||
OBJECT_DEREF(&tmp->next, "omapi_message_unregister");
|
||||
OBJECT_DEREF(&tmp->next);
|
||||
|
||||
if (n != NULL)
|
||||
OBJECT_REF(&tmp->next, n, "omapi_message_unregister");
|
||||
OBJECT_REF(&tmp->next, n);
|
||||
|
||||
OBJECT_DEREF(&tmp, "omapi_message_unregister");
|
||||
OBJECT_DEREF(&tmp);
|
||||
|
||||
} else {
|
||||
OBJECT_DEREF(&omapi_registered_messages,
|
||||
"omapi_message_unregister");
|
||||
OBJECT_DEREF(&omapi_registered_messages);
|
||||
if (n != NULL)
|
||||
OBJECT_REF(&omapi_registered_messages, n,
|
||||
"omapi_message_unregister");
|
||||
OBJECT_REF(&omapi_registered_messages, n);
|
||||
}
|
||||
|
||||
if (n != NULL)
|
||||
OBJECT_DEREF(&n, "omapi_message_unregister");
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
OBJECT_DEREF(&n);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
@ -492,7 +281,7 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
|
||||
* return an error.
|
||||
*/
|
||||
if (result == ISC_R_SUCCESS && create != 0 && exclusive != 0) {
|
||||
OBJECT_DEREF(&object, "omapi_message_process");
|
||||
OBJECT_DEREF(&object);
|
||||
return (omapi_protocol_send_status(po, NULL,
|
||||
ISC_R_EXISTS, message->id,
|
||||
"specified object already exists"));
|
||||
@ -502,7 +291,9 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
|
||||
* If we're creating the object, do it now.
|
||||
*/
|
||||
if (object == NULL) {
|
||||
result = omapi_object_create(&object, NULL, type);
|
||||
if (type->create == NULL)
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
result = (*(type->create))(&object, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (omapi_protocol_send_status(po, NULL,
|
||||
result, message->id,
|
||||
@ -518,7 +309,7 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
|
||||
message->object,
|
||||
message->handle);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
OBJECT_DEREF(&object, "omapi_message_process");
|
||||
OBJECT_DEREF(&object);
|
||||
return (omapi_protocol_send_status(po, NULL,
|
||||
result, message->id,
|
||||
"can't update object"));
|
||||
@ -541,13 +332,12 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
|
||||
send:
|
||||
result = omapi_protocol_send_update(po, NULL,
|
||||
message->id, object);
|
||||
OBJECT_DEREF(&object, "omapi_message_process");
|
||||
OBJECT_DEREF(&object);
|
||||
return (result);
|
||||
|
||||
case OMAPI_OP_UPDATE:
|
||||
if (m->object != NULL) {
|
||||
OBJECT_REF(&object, m->object,
|
||||
"omapi_message_process");
|
||||
OBJECT_REF(&object, m->object);
|
||||
} else {
|
||||
result = omapi_handle_lookup(&object, message->handle);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
@ -560,7 +350,7 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
|
||||
result = omapi_object_update(object, NULL, message->object,
|
||||
message->handle);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
OBJECT_DEREF(&object, "omapi_message_process");
|
||||
OBJECT_DEREF(&object);
|
||||
if (message->rid == 0)
|
||||
return (omapi_protocol_send_status(po, NULL,
|
||||
result, message->id,
|
||||
@ -627,10 +417,217 @@ omapi_message_process(omapi_object_t *mo, omapi_object_t *po) {
|
||||
"no remove method for object"));
|
||||
|
||||
result = (*(object->type->remove))(object, NULL);
|
||||
OBJECT_DEREF(&object, "omapi_message_process");
|
||||
OBJECT_DEREF(&object);
|
||||
|
||||
return (omapi_protocol_send_status(po, NULL, result,
|
||||
message->id, NULL));
|
||||
}
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
message_setvalue(omapi_object_t *h, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_typed_data_t *value)
|
||||
{
|
||||
omapi_message_object_t *m;
|
||||
|
||||
REQUIRE(h != NULL && h->type == omapi_type_message);
|
||||
|
||||
m = (omapi_message_object_t *)h;
|
||||
|
||||
/*
|
||||
* Can't set authlen.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Can set authenticator, but the value must be typed data.
|
||||
*/
|
||||
if (omapi_ds_strcmp(name, "authenticator") == 0) {
|
||||
if (m->authenticator != NULL)
|
||||
omapi_data_dereference(&m->authenticator);
|
||||
omapi_data_reference(&m->authenticator, value,
|
||||
"omapi_message_set_value");
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
} else if (omapi_ds_strcmp(name, "object") == 0) {
|
||||
INSIST(value != NULL && value->type == omapi_datatype_object);
|
||||
|
||||
if (m->object != NULL)
|
||||
OBJECT_DEREF(&m->object);
|
||||
OBJECT_REF(&m->object, value->u.object);
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
} else if (omapi_ds_strcmp(name, "notify-object") == 0) {
|
||||
INSIST(value != NULL && value->type == omapi_datatype_object);
|
||||
|
||||
if (m->notify_object != NULL)
|
||||
OBJECT_DEREF(&m->notify_object);
|
||||
OBJECT_REF(&m->notify_object, value->u.object);
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Can set authid, but it has to be an integer.
|
||||
*/
|
||||
} else if (omapi_ds_strcmp(name, "authid") == 0) {
|
||||
INSIST(value != NULL && value->type == omapi_datatype_int);
|
||||
|
||||
m->authid = value->u.integer;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Can set op, but it has to be an integer.
|
||||
*/
|
||||
} else if (omapi_ds_strcmp(name, "op") == 0) {
|
||||
INSIST(value != NULL && value->type == omapi_datatype_int);
|
||||
|
||||
m->op = value->u.integer;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Handle also has to be an integer.
|
||||
*/
|
||||
} else if (omapi_ds_strcmp(name, "handle") == 0) {
|
||||
INSIST(value != NULL && value->type == omapi_datatype_int);
|
||||
|
||||
m->h = value->u.integer;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Transaction ID has to be an integer.
|
||||
*/
|
||||
} else if (omapi_ds_strcmp(name, "id") == 0) {
|
||||
INSIST(value != NULL && value->type == omapi_datatype_int);
|
||||
|
||||
m->id = value->u.integer;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Remote transaction ID has to be an integer.
|
||||
*/
|
||||
} else if (omapi_ds_strcmp(name, "rid") == 0) {
|
||||
INSIST(value != NULL && value->type == omapi_datatype_int);
|
||||
|
||||
m->rid = value->u.integer;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to find some inner object that can take the value.
|
||||
*/
|
||||
PASS_SETVALUE(h);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
message_getvalue(omapi_object_t *h, omapi_object_t *id,
|
||||
omapi_data_string_t *name, omapi_value_t **value)
|
||||
{
|
||||
omapi_message_object_t *m;
|
||||
|
||||
REQUIRE(h != NULL && h->type == omapi_type_message);
|
||||
|
||||
m = (omapi_message_object_t *)h;
|
||||
|
||||
/*
|
||||
* Look for values that are in the message data structure.
|
||||
*/
|
||||
if (omapi_ds_strcmp(name, "authlen") == 0)
|
||||
return (omapi_make_int_value(value, name, (int)m->authlen,
|
||||
"omapi_message_get_value"));
|
||||
else if (omapi_ds_strcmp(name, "authenticator") == 0) {
|
||||
if (m->authenticator != NULL)
|
||||
return (omapi_make_value(value, name, m->authenticator,
|
||||
"omapi_message_get_value"));
|
||||
else
|
||||
return (ISC_R_NOTFOUND);
|
||||
} else if (omapi_ds_strcmp(name, "authid") == 0) {
|
||||
return (omapi_make_int_value(value, name, (int)m->authid,
|
||||
"omapi_message_get_value"));
|
||||
} else if (omapi_ds_strcmp(name, "op") == 0) {
|
||||
return (omapi_make_int_value(value, name, (int)m->op,
|
||||
"omapi_message_get_value"));
|
||||
} else if (omapi_ds_strcmp(name, "handle") == 0) {
|
||||
return (omapi_make_int_value(value, name, (int)m->handle,
|
||||
"omapi_message_get_value"));
|
||||
} else if (omapi_ds_strcmp(name, "id") == 0) {
|
||||
return (omapi_make_int_value(value, name, (int)m->id,
|
||||
"omapi_message_get_value"));
|
||||
} else if (omapi_ds_strcmp(name, "rid") == 0) {
|
||||
return (omapi_make_int_value(value, name, (int)m->rid,
|
||||
"omapi_message_get_value"));
|
||||
}
|
||||
|
||||
/*
|
||||
* See if there's an inner object that has the value.
|
||||
*/
|
||||
PASS_GETVALUE(h);
|
||||
}
|
||||
|
||||
static void
|
||||
message_destroy(omapi_object_t *handle) {
|
||||
omapi_message_object_t *message;
|
||||
|
||||
REQUIRE(handle != NULL && handle->type == omapi_type_message);
|
||||
|
||||
message = (omapi_message_object_t *)handle;
|
||||
|
||||
if (message->authenticator != NULL)
|
||||
omapi_data_dereference(&message->authenticator);
|
||||
|
||||
if (message->prev == NULL && omapi_registered_messages != message)
|
||||
omapi_message_unregister(handle);
|
||||
if (message->prev != NULL)
|
||||
OBJECT_DEREF(&message->prev);
|
||||
if (message->next != NULL)
|
||||
OBJECT_DEREF(&message->next);
|
||||
if (message->id_object != NULL)
|
||||
OBJECT_DEREF(&message->id_object);
|
||||
if (message->object != NULL)
|
||||
OBJECT_DEREF(&message->object);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
message_signalhandler(omapi_object_t *handle, const char *name,
|
||||
va_list ap) {
|
||||
omapi_message_object_t *message;
|
||||
|
||||
REQUIRE(handle != NULL && handle->type == omapi_type_message);
|
||||
|
||||
message = (omapi_message_object_t *)handle;
|
||||
|
||||
if (strcmp(name, "status") == 0 &&
|
||||
(message->object != NULL || message->notify_object != NULL)) {
|
||||
if (message->object != NULL)
|
||||
return ((message->object->type->signal_handler))
|
||||
(message->object, name, ap);
|
||||
else
|
||||
return ((message->notify_object->type->signal_handler))
|
||||
(message->notify_object, name, ap);
|
||||
}
|
||||
|
||||
PASS_SIGNAL(handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write all the published values associated with the object through the
|
||||
* specified connection.
|
||||
*/
|
||||
static isc_result_t
|
||||
message_stuffvalues(omapi_object_t *connection, omapi_object_t *id,
|
||||
omapi_object_t *message)
|
||||
{
|
||||
REQUIRE(message != NULL && message->type == omapi_type_message);
|
||||
|
||||
PASS_STUFFVALUES(message);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_message_init(void) {
|
||||
return (omapi_object_register(&omapi_type_message,
|
||||
"message",
|
||||
message_setvalue,
|
||||
message_getvalue,
|
||||
message_destroy,
|
||||
message_signalhandler,
|
||||
message_stuffvalues,
|
||||
NULL, NULL, NULL));
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: object.c,v 1.4 2000/01/14 23:10:03 tale Exp $ */
|
||||
/* $Id: object.c,v 1.5 2000/01/17 18:02:08 tale Exp $ */
|
||||
|
||||
/* Principal Author: Ted Lemon */
|
||||
|
||||
@ -30,12 +30,18 @@
|
||||
#include <omapi/private.h>
|
||||
|
||||
isc_result_t
|
||||
omapi_object_new(omapi_object_t **object, omapi_object_type_t *type,
|
||||
omapi_object_create(omapi_object_t **object, omapi_object_type_t *type,
|
||||
size_t size)
|
||||
{
|
||||
omapi_object_t *new;
|
||||
|
||||
REQUIRE(object != NULL && *object == NULL);
|
||||
REQUIRE(size > 0 || type == NULL);
|
||||
|
||||
if (type == NULL) {
|
||||
type = omapi_type_generic;
|
||||
size = sizeof(omapi_generic_object_t);
|
||||
}
|
||||
|
||||
new = isc_mem_get(omapi_mctx, size);
|
||||
if (new == NULL)
|
||||
@ -53,20 +59,16 @@ omapi_object_new(omapi_object_t **object, omapi_object_type_t *type,
|
||||
}
|
||||
|
||||
void
|
||||
omapi_object_reference(omapi_object_t **r, omapi_object_t *h,
|
||||
const char *name)
|
||||
{
|
||||
omapi_object_reference(omapi_object_t **r, omapi_object_t *h) {
|
||||
REQUIRE(r != NULL && *r == NULL);
|
||||
REQUIRE(h != NULL);
|
||||
|
||||
(void)name; /* Unused. */
|
||||
|
||||
*r = h;
|
||||
h->refcnt++;
|
||||
}
|
||||
|
||||
void
|
||||
omapi_object_dereference(omapi_object_t **h, const char *name) {
|
||||
omapi_object_dereference(omapi_object_t **h) {
|
||||
int outer_reference = 0;
|
||||
int inner_reference = 0;
|
||||
int handle_reference = 0;
|
||||
@ -83,7 +85,7 @@ omapi_object_dereference(omapi_object_t **h, const char *name) {
|
||||
*/
|
||||
/*
|
||||
* XXXDCL my wording
|
||||
* Note whether the object being dereference has an inner object, but
|
||||
* Note whether the object being dereferenced has an inner object, but
|
||||
* only if the inner object's own outer pointer is not what is
|
||||
* being dereferenced.
|
||||
* (XXXDCL when does it happen that way ?)
|
||||
@ -153,13 +155,14 @@ omapi_object_dereference(omapi_object_t **h, const char *name) {
|
||||
|
||||
if (extra_references == 0) {
|
||||
if (inner_reference != 0)
|
||||
OBJECT_DEREF(&(*h)->inner->outer, name);
|
||||
OBJECT_DEREF(&(*h)->inner->outer);
|
||||
if (outer_reference != 0)
|
||||
OBJECT_DEREF(&(*h)->outer->inner, name);
|
||||
OBJECT_DEREF(&(*h)->outer->inner);
|
||||
if ((*h)->type->destroy != NULL)
|
||||
(*((*h)->type->destroy))(*h, name);
|
||||
(*((*h)->type->destroy))(*h, NULL);
|
||||
isc_mem_put(omapi_mctx, *h, (*h)->object_size);
|
||||
}
|
||||
}
|
||||
|
||||
*h = NULL;
|
||||
}
|
||||
|
@ -78,22 +78,20 @@ omapi_protocol_connect(omapi_object_t *h, const char *server_name,
|
||||
isc_result_t result;
|
||||
omapi_protocol_object_t *obj;
|
||||
|
||||
obj = isc_mem_get(omapi_mctx, sizeof(*obj));
|
||||
if (obj == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
memset(obj, 0, sizeof(*obj));
|
||||
obj->object_size = sizeof(*obj);
|
||||
obj->refcnt = 1;
|
||||
obj->type = omapi_type_protocol;
|
||||
obj = NULL;
|
||||
result = omapi_object_create((omapi_object_t **)&obj,
|
||||
omapi_type_protocol, sizeof(*obj));
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
result = omapi_connection_toserver((omapi_object_t *)obj,
|
||||
server_name, port);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
OBJECT_DEREF(&obj, "omapi_protocol_connect");
|
||||
OBJECT_DEREF(&obj);
|
||||
return (result);
|
||||
}
|
||||
OBJECT_REF(&h->outer, obj, "omapi_protocol_connect");
|
||||
OBJECT_REF(&obj->inner, h, "omapi_protocol_connect");
|
||||
OBJECT_REF(&h->outer, obj);
|
||||
OBJECT_REF(&obj->inner, h);
|
||||
|
||||
/*
|
||||
* Send the introductory message.
|
||||
@ -102,13 +100,13 @@ omapi_protocol_connect(omapi_object_t *h, const char *server_name,
|
||||
OMAPI_PROTOCOL_VERSION,
|
||||
sizeof(omapi_protocol_header_t));
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
OBJECT_DEREF(&obj, "omapi_protocol_connect");
|
||||
OBJECT_DEREF(&obj);
|
||||
return (result);
|
||||
}
|
||||
|
||||
if (authinfo)
|
||||
OBJECT_REF(&obj->authinfo, authinfo, "omapi_protocol_connect");
|
||||
OBJECT_DEREF(&obj, "omapi_protocol_accept");
|
||||
OBJECT_REF(&obj->authinfo, authinfo);
|
||||
OBJECT_DEREF(&obj);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
@ -286,16 +284,56 @@ omapi_protocol_send_message(omapi_object_t *po, omapi_object_t *id,
|
||||
|
||||
|
||||
/*
|
||||
* When the client sends a message, it expects a reply.
|
||||
* When the client sends a message, it expects a reply. Increment
|
||||
* the count of messages_expected and make sure an isc_socket_recv
|
||||
* gets queued.
|
||||
*
|
||||
* If the connection is in the disconnecting state, connection_send
|
||||
* will note it, with an abort :-), in just a moment. In any event, it
|
||||
* is decreed to be a fatal error for the client program to call this
|
||||
* function after having asked to disconnect, so going ahead with the
|
||||
* omapi_connection_require call here in the driving thread (rather
|
||||
* than in the task thread, where omapi_protocol_signal_handler
|
||||
* normally does things) is ok. It is also known that if this is the
|
||||
* only message being sent right now, then there should be no other
|
||||
* recv_done() results coming in until after the
|
||||
* omapi_connection_require(), so some error is not going to be blowing
|
||||
* away the connection.
|
||||
*/
|
||||
if (connection->is_client) {
|
||||
RUNTIME_CHECK(isc_mutex_lock(&connection->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
|
||||
connection->messages_expected++;
|
||||
if (++connection->messages_expected == 1) {
|
||||
/*
|
||||
* omapi_connection_require() needs an unlocked mutex.
|
||||
*/
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
result = omapi_connection_require(c, p->header_size);
|
||||
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
/*
|
||||
* How could there possibly be that amount of bytes
|
||||
* waiting if no other messages were outstanding?
|
||||
* Answer: it shouldn't be possible. Make sure.
|
||||
*/
|
||||
ENSURE(result != ISC_R_SUCCESS);
|
||||
if (result != OMAPI_R_NOTYET)
|
||||
goto disconnect;
|
||||
|
||||
} else
|
||||
/*
|
||||
* If messages_expected > 1, then the code after the
|
||||
* call to omapi_message_process() in the
|
||||
* omapi_protocol_signal_handler function has not yet
|
||||
* been done, so it will handle the call to
|
||||
* omapi_connection_require while messages_expected
|
||||
* remains non-zero. (This check also happens at
|
||||
* the end of the block that processes the intro
|
||||
* message.)
|
||||
*/
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&connection->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
connection_send(connection);
|
||||
@ -367,6 +405,12 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
/*
|
||||
* The next thing that shows up on incoming connections
|
||||
* should be a message header.
|
||||
*/
|
||||
p->state = omapi_protocol_header_wait;
|
||||
|
||||
/*
|
||||
* Signal omapi_connection_wait() to wake up.
|
||||
* Only do this for the client side.
|
||||
@ -383,36 +427,53 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
|
||||
ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* 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 the driving program has already called
|
||||
* omapi_protocol_send_message and the lock
|
||||
* was acquired in that function, then since
|
||||
* messages_expected would have been >= 2 at
|
||||
* the critical test, the omapi_connection_require
|
||||
* would not have been done yet, and will need
|
||||
* to be. Since messages_expected was decremented,
|
||||
* drop through to the connection_require only if
|
||||
* messages_expected is >= 1
|
||||
*/
|
||||
if (c->messages_expected == 0) {
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&c->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Proceed to the omapi_connection_require
|
||||
* for the first "real" message's header.
|
||||
*/
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&c->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
|
||||
}
|
||||
|
||||
to_header_wait:
|
||||
/*
|
||||
* The next thing we're expecting is a message header.
|
||||
*/
|
||||
p->state = omapi_protocol_header_wait;
|
||||
|
||||
/*
|
||||
* Register a need for the number of bytes in a
|
||||
* header, and if we already have that many, process
|
||||
* them immediately.
|
||||
* Register a need for the number of bytes in a header, and if
|
||||
* that many are here already, process them immediately.
|
||||
*
|
||||
* XXXDCL there is a miniscule but non-zero chance that
|
||||
* omapi_connection_require will return ISC_R_NOMEMORY
|
||||
* from omapi_connection_require. If that happens,
|
||||
* as things are currently written the client will likely
|
||||
* just hang. no recv was queued, so no recv_done will get
|
||||
* called, so this signal handler never gets called again.
|
||||
*/
|
||||
if ((omapi_connection_require(connection, p->header_size))
|
||||
!= ISC_R_SUCCESS)
|
||||
result = omapi_connection_require(connection, p->header_size);
|
||||
if (result == OMAPI_R_NOTYET)
|
||||
break;
|
||||
/*
|
||||
* If we already have the data, fall through.
|
||||
*/
|
||||
else if (result != ISC_R_SUCCESS)
|
||||
goto disconnect;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case omapi_protocol_header_wait:
|
||||
result = omapi_message_new((omapi_object_t **)&p->message,
|
||||
"omapi_protocol_signal_handler");
|
||||
result = omapi_message_new((omapi_object_t **)&p->message);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto disconnect;
|
||||
|
||||
@ -464,11 +525,13 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
|
||||
/*
|
||||
* Wait for a 16-bit length.
|
||||
*/
|
||||
if (omapi_connection_require(connection, 2) != ISC_R_SUCCESS)
|
||||
result = omapi_connection_require(connection, 2);
|
||||
if (result == OMAPI_R_NOTYET)
|
||||
break;
|
||||
/*
|
||||
* If it's already here, fall through.
|
||||
*/
|
||||
else if (result != ISC_R_SUCCESS)
|
||||
goto disconnect;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case omapi_protocol_name_length_wait:
|
||||
result = omapi_connection_getuint16(connection, &nlen);
|
||||
@ -511,11 +574,14 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
|
||||
* the authenticator. If we already have it,
|
||||
* go read it in.
|
||||
*/
|
||||
if (omapi_connection_require(connection,
|
||||
p->message->authlen)
|
||||
== ISC_R_SUCCESS)
|
||||
result = omapi_connection_require(connection,
|
||||
p->message->authlen);
|
||||
if (result == OMAPI_R_NOTYET)
|
||||
break;
|
||||
else if (result == ISC_R_SUCCESS)
|
||||
goto signature_wait;
|
||||
break;
|
||||
else
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -527,14 +593,14 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
|
||||
goto disconnect;
|
||||
|
||||
p->state = omapi_protocol_name_wait;
|
||||
if (omapi_connection_require(connection, nlen) !=
|
||||
ISC_R_SUCCESS)
|
||||
result = omapi_connection_require(connection, nlen);
|
||||
if (result == OMAPI_R_NOTYET)
|
||||
break;
|
||||
else if (result != ISC_R_SUCCESS)
|
||||
goto disconnect;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
/*
|
||||
* If it's already here, fall through.
|
||||
* */
|
||||
|
||||
case omapi_protocol_name_wait:
|
||||
result = omapi_connection_copyout(p->name->value, connection,
|
||||
p->name->len);
|
||||
@ -546,12 +612,12 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
|
||||
*/
|
||||
p->state = omapi_protocol_value_length_wait;
|
||||
result = omapi_connection_require(connection, 4);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result == OMAPI_R_NOTYET)
|
||||
break;
|
||||
else if (result != ISC_R_SUCCESS)
|
||||
goto disconnect;
|
||||
|
||||
/*
|
||||
* If it's already here, fall through.
|
||||
*/
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case omapi_protocol_value_length_wait:
|
||||
omapi_connection_getuint32(connection, &vlen);
|
||||
@ -571,8 +637,10 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
|
||||
|
||||
p->state = omapi_protocol_value_wait;
|
||||
result = omapi_connection_require(connection, vlen);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result == OMAPI_R_NOTYET)
|
||||
break;
|
||||
else if (result != ISC_R_SUCCESS)
|
||||
goto disconnect;
|
||||
/*
|
||||
* If it's already here, fall through.
|
||||
*/
|
||||
@ -595,8 +663,9 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
|
||||
* We need a generic object to hang off of the
|
||||
* incoming message.
|
||||
*/
|
||||
result = omapi_generic_new(&p->message->object,
|
||||
"omapi_protocol_signal_handler");
|
||||
result =
|
||||
omapi_object_create(&p->message->object,
|
||||
NULL, 0);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto disconnect;
|
||||
}
|
||||
@ -611,8 +680,7 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
|
||||
|
||||
omapi_data_stringdereference(&p->name,
|
||||
"omapi_protocol_signal_handler");
|
||||
omapi_data_dereference(&p->value,
|
||||
"omapi_protocol_signal_handler");
|
||||
omapi_data_dereference(&p->value);
|
||||
goto need_name_length;
|
||||
|
||||
signature_wait:
|
||||
@ -639,6 +707,18 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
|
||||
result = omapi_message_process((omapi_object_t *)p->message,
|
||||
h);
|
||||
|
||||
/* XXXTL unbind the authenticator. */
|
||||
|
||||
/*
|
||||
* Free the message object.
|
||||
*/
|
||||
OBJECT_DEREF(&p->message);
|
||||
|
||||
/*
|
||||
* The next thing the protocol reads will be a new message.
|
||||
*/
|
||||
p->state = omapi_protocol_header_wait;
|
||||
|
||||
/*
|
||||
* Signal omapi_connection_wait() to wake up.
|
||||
* XXXDCL duplicated from above.
|
||||
@ -653,23 +733,32 @@ omapi_protocol_signal_handler(omapi_object_t *h, const char *name, va_list ap)
|
||||
RUNTIME_CHECK(isc_condition_signal(&c->waiter) ==
|
||||
ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* If there are no more messages expected, exit
|
||||
* the signal handler.
|
||||
*/
|
||||
if (c->messages_expected == 0) {
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&c->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
break;
|
||||
}
|
||||
|
||||
RUNTIME_CHECK(isc_mutex_unlock(&c->mutex) ==
|
||||
ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
/* XXXTL unbind the authenticator. */
|
||||
|
||||
/*
|
||||
* Free the message object.
|
||||
* Proceed to the omapi_connection_require for the next
|
||||
* message's header.
|
||||
*/
|
||||
OBJECT_DEREF(&p->message, "omapi_protocol_signal_handler");
|
||||
|
||||
/*
|
||||
* XXXDCL these gotos could be cleared up with one
|
||||
* more variable to control a loop around the switch.
|
||||
*/
|
||||
fprintf(stderr, "going to header_wait, events_pending = %d\n",
|
||||
c->events_pending);
|
||||
fprintf(stderr, "going to header_wait, events_pending = %d"
|
||||
" messages_expected = %d\n", c->events_pending,
|
||||
c->messages_expected);
|
||||
goto to_header_wait;
|
||||
|
||||
default:
|
||||
@ -712,7 +801,7 @@ omapi_protocol_get_value(omapi_object_t *h, omapi_object_t *id,
|
||||
}
|
||||
|
||||
void
|
||||
omapi_protocol_destroy(omapi_object_t *h, const char *name) {
|
||||
omapi_protocol_destroy(omapi_object_t *h) {
|
||||
omapi_protocol_object_t *p;
|
||||
|
||||
REQUIRE(h != NULL && h->type == omapi_type_protocol);
|
||||
@ -720,10 +809,10 @@ omapi_protocol_destroy(omapi_object_t *h, const char *name) {
|
||||
p = (omapi_protocol_object_t *)h;
|
||||
|
||||
if (p->message != NULL)
|
||||
OBJECT_DEREF(&p->message, name);
|
||||
OBJECT_DEREF(&p->message);
|
||||
|
||||
if (p->authinfo != NULL)
|
||||
OBJECT_DEREF(&p->authinfo, name);
|
||||
OBJECT_DEREF(&p->authinfo);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -758,12 +847,12 @@ omapi_protocol_listen(omapi_object_t *h, int port, int max) {
|
||||
obj->refcnt = 1;
|
||||
obj->type = omapi_type_protocol_listener;
|
||||
|
||||
OBJECT_REF(&h->outer, obj, "omapi_protocol_listen");
|
||||
OBJECT_REF(&obj->inner, h, "omapi_protocol_listen");
|
||||
OBJECT_REF(&h->outer, obj);
|
||||
OBJECT_REF(&obj->inner, h);
|
||||
|
||||
result = omapi_listener_listen((omapi_object_t *)obj, port, max);
|
||||
|
||||
OBJECT_DEREF(&obj, "omapi_protocol_listen");
|
||||
OBJECT_DEREF(&obj);
|
||||
return (result);
|
||||
}
|
||||
|
||||
@ -800,8 +889,8 @@ omapi_protocol_listener_signal(omapi_object_t *h, const char *name, va_list ap)
|
||||
* connection.
|
||||
*/
|
||||
obj = NULL;
|
||||
result = omapi_object_new((omapi_object_t **)&obj, omapi_type_protocol,
|
||||
sizeof(*obj));
|
||||
result = omapi_object_create((omapi_object_t **)&obj,
|
||||
omapi_type_protocol, sizeof(*obj));
|
||||
if (result != ISC_R_SUCCESS)
|
||||
/*
|
||||
* When the unsuccessful return value is percolated back to
|
||||
@ -814,8 +903,8 @@ omapi_protocol_listener_signal(omapi_object_t *h, const char *name, va_list ap)
|
||||
* Tie the protocol object bidirectionally to the connection
|
||||
* object, with the connection as the outer object.
|
||||
*/
|
||||
OBJECT_REF(&obj->outer, c, "omapi_protocol_accept");
|
||||
OBJECT_REF(&c->inner, obj, "omapi_protocol_accept");
|
||||
OBJECT_REF(&obj->outer, c);
|
||||
OBJECT_REF(&c->inner, obj);
|
||||
|
||||
/*
|
||||
* Send the introductory message.
|
||||
@ -833,7 +922,7 @@ omapi_protocol_listener_signal(omapi_object_t *h, const char *name, va_list ap)
|
||||
* XXXDCL aigh, this is so confusing. I don't think the
|
||||
* right thing is being done.
|
||||
*/
|
||||
OBJECT_DEREF(&c->inner, "omapi_protocol_accept");
|
||||
OBJECT_DEREF(&c->inner);
|
||||
|
||||
/*
|
||||
* Remove one of the references to the object, so it will be
|
||||
@ -841,7 +930,7 @@ omapi_protocol_listener_signal(omapi_object_t *h, const char *name, va_list ap)
|
||||
* XXXDCL this is what ted did, but i'm not sure my explanation
|
||||
* is correct.
|
||||
*/
|
||||
OBJECT_DEREF(&obj, "omapi_protocol_accept");
|
||||
OBJECT_DEREF(&obj);
|
||||
|
||||
return (result);
|
||||
}
|
||||
@ -867,10 +956,10 @@ omapi_protocol_listener_get_value(omapi_object_t *h, omapi_object_t *id,
|
||||
}
|
||||
|
||||
void
|
||||
omapi_protocol_listener_destroy(omapi_object_t *h, const char *name) {
|
||||
omapi_protocol_listener_destroy(omapi_object_t *h) {
|
||||
REQUIRE(h != NULL && h->type == omapi_type_protocol_listener);
|
||||
|
||||
(void)name; /* Unused. */
|
||||
/* XXXDCL currently NOTHING */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -898,7 +987,7 @@ omapi_protocol_send_status(omapi_object_t *po, omapi_object_t *id,
|
||||
|
||||
REQUIRE(po != NULL && po->type == omapi_type_protocol);
|
||||
|
||||
result = omapi_message_new(&message, "omapi_protocol_send_status");
|
||||
result = omapi_message_new(&message);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
@ -918,7 +1007,7 @@ omapi_protocol_send_status(omapi_object_t *po, omapi_object_t *id,
|
||||
result = omapi_set_string_value(message, NULL, "message", msg);
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
OBJECT_DEREF(&message, "omapi_protocol_send_status");
|
||||
OBJECT_DEREF(&message);
|
||||
return (result);
|
||||
}
|
||||
|
||||
@ -934,7 +1023,7 @@ omapi_protocol_send_update(omapi_object_t *po, omapi_object_t *id,
|
||||
|
||||
REQUIRE(po != NULL && po->type == omapi_type_protocol);
|
||||
|
||||
result = omapi_message_new(&message, "omapi_protocol_send_update");
|
||||
result = omapi_message_new(&message);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
@ -958,7 +1047,7 @@ omapi_protocol_send_update(omapi_object_t *po, omapi_object_t *id,
|
||||
"object", object);
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
OBJECT_DEREF(&message, "dhcpctl_open_object");
|
||||
OBJECT_DEREF(&message);
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
@ -27,13 +27,9 @@
|
||||
|
||||
omapi_object_type_t *omapi_type_connection;
|
||||
omapi_object_type_t *omapi_type_listener;
|
||||
omapi_object_type_t *omapi_type_io_object;
|
||||
omapi_object_type_t *omapi_type_datagram;
|
||||
omapi_object_type_t *omapi_type_generic;
|
||||
omapi_object_type_t *omapi_type_protocol;
|
||||
omapi_object_type_t *omapi_type_protocol_listener;
|
||||
omapi_object_type_t *omapi_type_waiter;
|
||||
omapi_object_type_t *omapi_type_remote;
|
||||
omapi_object_type_t *omapi_type_message;
|
||||
|
||||
omapi_object_type_t *omapi_object_types;
|
||||
@ -41,7 +37,6 @@ int omapi_object_type_count;
|
||||
|
||||
isc_mem_t *omapi_mctx;
|
||||
isc_taskmgr_t *omapi_taskmgr;
|
||||
isc_timermgr_t *omapi_timermgr;
|
||||
isc_socketmgr_t *omapi_socketmgr;
|
||||
|
||||
isc_boolean_t omapi_ipv6 = ISC_FALSE;
|
||||
@ -74,64 +69,27 @@ omapi_init(isc_mem_t *mctx) {
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
omapi_timermgr = NULL;
|
||||
result = isc_timermgr_create(omapi_mctx, &omapi_timermgr);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
if (isc_net_probeipv6() == ISC_R_SUCCESS)
|
||||
omapi_ipv6 = ISC_TRUE;
|
||||
else
|
||||
omapi_ipv6 = ISC_FALSE;
|
||||
|
||||
/*
|
||||
* Register all the standard object types.
|
||||
* Initialize all the standard object types.
|
||||
*/
|
||||
result = omapi_object_type_register(&omapi_type_connection,
|
||||
"connection",
|
||||
omapi_connection_setvalue,
|
||||
omapi_connection_getvalue,
|
||||
omapi_connection_destroy,
|
||||
omapi_connection_signalhandler,
|
||||
omapi_connection_stuffvalues,
|
||||
0, 0, 0);
|
||||
result = omapi_generic_init();
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
result = omapi_object_type_register(&omapi_type_listener,
|
||||
"listener",
|
||||
omapi_listener_setvalue,
|
||||
omapi_listener_getvalue,
|
||||
omapi_listener_destroy,
|
||||
omapi_listener_signalhandler,
|
||||
omapi_listener_stuffvalues,
|
||||
0, 0, 0);
|
||||
result = omapi_listener_init();
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
result = omapi_object_type_register(&omapi_type_io_object,
|
||||
"io",
|
||||
omapi_io_setvalue,
|
||||
omapi_io_getvalue,
|
||||
omapi_io_destroy,
|
||||
omapi_io_signalhandler,
|
||||
omapi_io_stuffvalues,
|
||||
0, 0, 0);
|
||||
result = omapi_connection_init();
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
result = omapi_object_type_register(&omapi_type_generic,
|
||||
"generic",
|
||||
omapi_generic_set_value,
|
||||
omapi_generic_get_value,
|
||||
omapi_generic_destroy,
|
||||
omapi_generic_signal_handler,
|
||||
omapi_generic_stuff_values,
|
||||
0, 0, 0);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
result = omapi_object_type_register(&omapi_type_protocol,
|
||||
result = omapi_object_register(&omapi_type_protocol,
|
||||
"protocol",
|
||||
omapi_protocol_set_value,
|
||||
omapi_protocol_get_value,
|
||||
@ -142,7 +100,7 @@ omapi_init(isc_mem_t *mctx) {
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
result = omapi_object_type_register(&omapi_type_protocol_listener,
|
||||
result = omapi_object_register(&omapi_type_protocol_listener,
|
||||
"protocol-listener",
|
||||
omapi_protocol_listener_set_value,
|
||||
omapi_protocol_listener_get_value,
|
||||
@ -153,45 +111,32 @@ omapi_init(isc_mem_t *mctx) {
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
result = omapi_object_type_register(&omapi_type_message,
|
||||
"message",
|
||||
omapi_message_setvalue,
|
||||
omapi_message_getvalue,
|
||||
omapi_message_destroy,
|
||||
omapi_message_signalhandler,
|
||||
omapi_message_stuffvalues,
|
||||
0, 0, 0);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
result = omapi_object_type_register(&omapi_type_waiter,
|
||||
"waiter",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
omapi_waiter_signal_handler, 0,
|
||||
0, 0, 0);
|
||||
result = omapi_message_init();
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* This does not free connections and other in-use objects, only the
|
||||
* things created by omapi_init(). It is the callers responsibility to
|
||||
* free the other things (as via omapi_connection_disconnect or
|
||||
* omapi_object_dereference).
|
||||
*/
|
||||
void
|
||||
omapi_shutdown() {
|
||||
omapi_destroy() {
|
||||
omapi_object_type_t *type, *next_type;
|
||||
|
||||
isc_socketmgr_destroy(&omapi_socketmgr);
|
||||
isc_taskmgr_destroy(&omapi_taskmgr);
|
||||
isc_timermgr_destroy(&omapi_timermgr);
|
||||
|
||||
for (type = omapi_object_types; type != NULL; type = next_type) {
|
||||
next_type = type->next;
|
||||
isc_mem_put(omapi_mctx, type, sizeof(*type));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_object_type_register(omapi_object_type_t **type, const char *name,
|
||||
omapi_object_register(omapi_object_type_t **type, const char *name,
|
||||
isc_result_t (*set_value)
|
||||
(omapi_object_t *,
|
||||
omapi_object_t *,
|
||||
@ -205,8 +150,7 @@ omapi_object_type_register(omapi_object_type_t **type, const char *name,
|
||||
omapi_value_t **),
|
||||
|
||||
void (*destroy)
|
||||
(omapi_object_t *,
|
||||
const char *),
|
||||
(omapi_object_t *),
|
||||
|
||||
isc_result_t (*signal_handler)
|
||||
(omapi_object_t *,
|
||||
@ -341,7 +285,7 @@ omapi_set_boolean_value(omapi_object_t *h, omapi_object_t *id,
|
||||
|
||||
result = omapi_set_value(h, id, n, tv);
|
||||
omapi_data_stringdereference(&n, "omapi_set_boolean_value");
|
||||
omapi_data_dereference(&tv, "omapi_set_boolean_value");
|
||||
omapi_data_dereference(&tv);
|
||||
return (result);
|
||||
}
|
||||
|
||||
@ -367,7 +311,7 @@ omapi_set_int_value(omapi_object_t *h, omapi_object_t *id,
|
||||
|
||||
result = omapi_set_value(h, id, n, tv);
|
||||
omapi_data_stringdereference(&n, "omapi_set_int_value");
|
||||
omapi_data_dereference(&tv, "omapi_set_int_value");
|
||||
omapi_data_dereference(&tv);
|
||||
return (result);
|
||||
}
|
||||
|
||||
@ -393,7 +337,7 @@ omapi_set_object_value(omapi_object_t *h, omapi_object_t *id,
|
||||
|
||||
result = omapi_set_value(h, id, n, tv);
|
||||
omapi_data_stringdereference(&n, "omapi_set_object_value");
|
||||
omapi_data_dereference(&tv, "omapi_set_object_value");
|
||||
omapi_data_dereference(&tv);
|
||||
return (result);
|
||||
}
|
||||
|
||||
@ -419,7 +363,7 @@ omapi_set_string_value(omapi_object_t *h, omapi_object_t *id,
|
||||
|
||||
result = omapi_set_value(h, id, n, tv);
|
||||
omapi_data_stringdereference(&n, "omapi_set_string_value");
|
||||
omapi_data_dereference(&tv, "omapi_set_string_value");
|
||||
omapi_data_dereference(&tv);
|
||||
return (result);
|
||||
}
|
||||
|
||||
@ -469,18 +413,6 @@ omapi_stuff_values(omapi_object_t *c, omapi_object_t *id, omapi_object_t *o) {
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_object_create(omapi_object_t **obj, omapi_object_t *id,
|
||||
omapi_object_type_t *type)
|
||||
{
|
||||
REQUIRE(type != NULL);
|
||||
|
||||
if (type->create == NULL)
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
|
||||
return ((*(type->create))(obj, id));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_object_update(omapi_object_t *obj, omapi_object_t *id,
|
||||
omapi_object_t *src, omapi_handle_t handle)
|
||||
|
Loading…
x
Reference in New Issue
Block a user