diff --git a/lib/omapi/connection.c b/lib/omapi/connection.c index 79b74c8662..8e5002f559 100644 --- a/lib/omapi/connection.c +++ b/lib/omapi/connection.c @@ -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)); +} diff --git a/lib/omapi/data.c b/lib/omapi/data.c index 505c9d4c22..f606aad322 100644 --- a/lib/omapi/data.c +++ b/lib/omapi/data.c @@ -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; diff --git a/lib/omapi/dispatch.c b/lib/omapi/dispatch.c index 0a07fd2e88..35394e1916 100644 --- a/lib/omapi/dispatch.c +++ b/lib/omapi/dispatch.c @@ -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); -} - diff --git a/lib/omapi/generic.c b/lib/omapi/generic.c index 1429707658..931110ca0e 100644 --- a/lib/omapi/generic.c +++ b/lib/omapi/generic.c @@ -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 +#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)); +} diff --git a/lib/omapi/handle.c b/lib/omapi/handle.c index feba1e467b..bf821ec668 100644 --- a/lib/omapi/handle.c +++ b/lib/omapi/handle.c @@ -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); } diff --git a/lib/omapi/include/omapi/omapip.h b/lib/omapi/include/omapi/omapip.h index 7f82038425..5f433dca68 100644 --- a/lib/omapi/include/omapi/omapip.h +++ b/lib/omapi/include/omapi/omapip.h @@ -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, diff --git a/lib/omapi/include/omapi/private.h b/lib/omapi/include/omapi/private.h index 856fddb1a5..e5a4e20ee6 100644 --- a/lib/omapi/include/omapi/private.h +++ b/lib/omapi/include/omapi/private.h @@ -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 */ diff --git a/lib/omapi/listener.c b/lib/omapi/listener.c index 2e94f52af7..e772fed310 100644 --- a/lib/omapi/listener.c +++ b/lib/omapi/listener.c @@ -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)); +} diff --git a/lib/omapi/message.c b/lib/omapi/message.c index 24ab62757d..2d2a2c4cd4 100644 --- a/lib/omapi/message.c +++ b/lib/omapi/message.c @@ -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)); +} diff --git a/lib/omapi/object.c b/lib/omapi/object.c index b8733d571b..ae16eb6073 100644 --- a/lib/omapi/object.c +++ b/lib/omapi/object.c @@ -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 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; } diff --git a/lib/omapi/protocol.c b/lib/omapi/protocol.c index ba350b622b..33f3e42f6b 100644 --- a/lib/omapi/protocol.c +++ b/lib/omapi/protocol.c @@ -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); } diff --git a/lib/omapi/support.c b/lib/omapi/support.c index b821c267c7..c610452185 100644 --- a/lib/omapi/support.c +++ b/lib/omapi/support.c @@ -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)