Beispiel #1
0
void rpc_ss_destroy_callee_context
(
    dce_uuid_t *p_uuid,             /* Pointer to UUID of context to be destroyed */
    handle_t  h,                /* Binding handle */
    error_status_t *result /* Function result */
)    /* Returns error_status_ok unless the UUID is not in the lookup table */
{
    rpc_client_handle_t close_client;   /* NULL or client to stop monitoring */

#ifdef PERFMON
    RPC_SS_DESTROY_CALLEE_CONTEXT_N;
#endif

    RPC_SS_THREADS_MUTEX_LOCK(&rpc_ss_context_table_mutex);
    DPRINT(("Seized context tables\n"));
    rpc_ss_lkddest_callee_context(p_uuid,&close_client,result);
    RPC_SS_THREADS_MUTEX_UNLOCK(&rpc_ss_context_table_mutex);
    DPRINT(("Released context tables\n"));
    if ((*result == error_status_ok) && (close_client != NULL))
    {
        rpc_network_stop_monitoring(h, close_client, (error_status_t *) result);
    }
#ifdef PERFMON
    RPC_SS_DESTROY_CALLEE_CONTEXT_X;
#endif
}
Beispiel #2
0
void rpc_ss_update_callee_context
(
    rpc_ss_context_t    callee_context, /* The user's local form of the context */
    dce_uuid_t              *p_uuid,        /* Pointer to the equivalent UUID */
    error_status_t      *result         /* Function result */
)
{
    callee_context_entry_t *this_link;

#ifdef PERFMON
    RPC_SS_UPDATE_CALLEE_CONTEXT_N;
#endif

    RPC_SS_THREADS_MUTEX_LOCK(&rpc_ss_context_table_mutex);
    DPRINT(("Seized context tables\n"));
    this_link = &context_table[dce_uuid_hash(p_uuid,result)
                                               % CALLEE_CONTEXT_TABLE_SIZE];
    while ( ! dce_uuid_equal(p_uuid,&this_link->uuid,result) )
    {
        this_link = this_link->next_context;
        if (this_link == NULL)
        {
            RPC_SS_THREADS_MUTEX_UNLOCK(&rpc_ss_context_table_mutex);
            DPRINT(("Released context tables\n"));
            DCETHREAD_RAISE( rpc_x_ss_context_mismatch);
        }
    }
    this_link->user_context = callee_context;
    RPC_SS_THREADS_MUTEX_UNLOCK(&rpc_ss_context_table_mutex);
    DPRINT(("Released context tables\n"));
    *result = error_status_ok;

#ifdef PERFMON
    RPC_SS_UPDATE_CALLEE_CONTEXT_X;
#endif

}
Beispiel #3
0
void rpc_ss_ee_ctx_from_wire
(
    ndr_context_handle      *p_wire_context,
    rpc_ss_context_t        *p_context,         /* The application context */
    volatile error_status_t *p_st
)
{
    dce_uuid_t *p_uuid;    /* Pointer to the UUID that has come off the wire */
    callee_context_entry_t *this_link;

#ifdef PERFMON
    RPC_SS_EE_CTX_FROM_WIRE_N;
#endif

    p_uuid = &p_wire_context->context_handle_uuid;

#ifdef DEBUGCTX
    debug_context_lookup(p_uuid);
    debug_context_table();
#endif

    *p_st = error_status_ok;
    if ( dce_uuid_is_nil(p_uuid, (error_status_t *)p_st) )
    {
        *p_context = NULL;

#ifdef PERFMON
        RPC_SS_EE_CTX_FROM_WIRE_X;
#endif

        return;
    }
    RPC_SS_THREADS_MUTEX_LOCK(&rpc_ss_context_table_mutex);
    DPRINT(("Seized context tables\n"));
    this_link = &context_table[dce_uuid_hash(p_uuid, (error_status_t *)p_st)
                                               % CALLEE_CONTEXT_TABLE_SIZE];
    while ( ! dce_uuid_equal(p_uuid,&this_link->uuid, (error_status_t *)p_st) )
    {
        this_link = this_link->next_context;
        if (this_link == NULL)
        {
            RPC_SS_THREADS_MUTEX_UNLOCK(&rpc_ss_context_table_mutex);
            DPRINT(("Released context tables\n"));

#ifdef PERFMON
            RPC_SS_EE_CTX_FROM_WIRE_X;
#endif

            DCETHREAD_RAISE( rpc_x_ss_context_mismatch );
            return;
        }
    }
    *p_context = this_link->user_context;
    RPC_SS_THREADS_MUTEX_UNLOCK(&rpc_ss_context_table_mutex);
    DPRINT(("Released context tables\n"));

#ifdef PERFMON
    RPC_SS_EE_CTX_FROM_WIRE_X;
#endif

    return;
}
Beispiel #4
0
void rpc_ss_create_callee_context
(
    rpc_ss_context_t callee_context,/* The user's local form of the context */
    dce_uuid_t    *p_uuid,              /* Pointer to the equivalent UUID */
    handle_t h,                     /* Binding handle */
    ctx_rundown_fn_p_t ctx_rundown, /* Pointer to context rundown routine */
    error_status_t *result     /* Function result */
)
{
    rpc_client_handle_t  ctx_client;         /* ID of client owning context */
    callee_context_entry_t *this_link, *next_link, * volatile new_link;
    ndr_boolean is_new_client;

    //DO_NOT_CLOBBER(new_link);

#ifdef PERFMON
    RPC_SS_CREATE_CALLEE_CONTEXT_N;
#endif

    /* If this is the first context to be created, initialization is needed */
    RPC_SS_INIT_CONTEXT

    rpc_binding_inq_client(h, &ctx_client, (error_status_t *) result);
    if (*result != error_status_ok) return;

    RPC_SS_THREADS_MUTEX_LOCK(&rpc_ss_context_table_mutex);
    DPRINT(("Seized context tables\n"));
    this_link = &context_table[dce_uuid_hash(p_uuid,(error_status_t *)result)
                                               % CALLEE_CONTEXT_TABLE_SIZE];
    if ( dce_uuid_is_nil(&this_link->uuid, (error_status_t *)result) )
    {
        /* Home slot in the hash table is empty */
        new_link = this_link;
        next_link = NULL;
    }
    else
    {
        /* Put the new item at the head of the overflow chain */
        new_link = (callee_context_entry_t *)
                             malloc(sizeof(callee_context_entry_t));
        if (new_link == NULL)
        {
            RPC_SS_THREADS_MUTEX_UNLOCK(&rpc_ss_context_table_mutex);
            DPRINT(("Released context tables\n"));
            DCETHREAD_RAISE( rpc_x_no_memory );
        }
        next_link = this_link->next_context;
        this_link->next_context = new_link;
    }

    /* Fill in fields of context entry */
    memcpy(
        (char *)&new_link->uuid,
        (char *)p_uuid,
        sizeof(dce_uuid_t)
    );
    new_link->user_context = callee_context;
    new_link->rundown = ctx_rundown;
    new_link->next_context = next_link;

    DCETHREAD_TRY
    rpc_ss_add_to_callee_client(ctx_client,new_link,&is_new_client,
                                result);
    DCETHREAD_FINALLY
    RPC_SS_THREADS_MUTEX_UNLOCK(&rpc_ss_context_table_mutex);
    DPRINT(("Released context tables\n"));
    DCETHREAD_ENDTRY
    if ((*result == error_status_ok) && is_new_client)
    {
        rpc_network_monitor_liveness( h, ctx_client,
                             rpc_ss_rundown_client,
                             (error_status_t *) result );
#ifdef PERFMON
    RPC_SS_CREATE_CALLEE_CONTEXT_X;
#endif
    }
}
Beispiel #5
0
void rpc_ss_rundown_client
(
    /* [in] */ rpc_client_handle_t failed_client
)
{
    error_status_t result;
    callee_client_entry_t *this_client;
    callee_context_entry_t *this_context;
    rpc_client_handle_t close_client = NULL;
                                       /* NULL or client to stop monitoring */
    /* FIXME: is the volatility set correctly here? */
    rpc_ss_rundown_list_elt * volatile rundown_list;
    rpc_ss_rundown_list_elt * volatile rundown_elt;
	 
    rundown_list = NULL;

#ifdef PERFMON
    RPC_SS_RUNDOWN_CLIENT_N;
#endif

    RPC_SS_THREADS_MUTEX_LOCK(&rpc_ss_context_table_mutex);
    DPRINT(("Seized context tables\n"));
    for( this_client = &client_table[HASH_CLIENT_ID(failed_client)];
         (this_client != NULL) && (close_client == NULL);
         this_client = this_client->next_h_client )
    {
        if (this_client->client == failed_client)
        {
            while (this_client->ref_count != 0)
            {
                this_client->rundown_pending = idl_true;
                RPC_SS_THREADS_CONDITION_WAIT(&this_client->cond_var,
                                              &rpc_ss_context_table_mutex);
                                        /* Mutex has been released */
                RPC_SS_THREADS_MUTEX_LOCK(&rpc_ss_context_table_mutex);
            }
            if (this_client->count == 0)
            {
                /* The manager closed the contexts while a rundown was
                        pending */
                rpc_ss_ctx_remove_client_entry(this_client);
                RPC_SS_THREADS_MUTEX_UNLOCK(&rpc_ss_context_table_mutex);
                DPRINT(("Released context tables\n"));
#ifdef PERFMON
                RPC_SS_RUNDOWN_CLIENT_X;
#endif
                return;
            }
            /* Need to clear the rundown pending flag so that the client
                entry can be deleted */
            this_client->rundown_pending = idl_false;
            while (close_client == NULL)
            {
                /* Loop until all contexts for this client have been removed
                    from the context table. Note that each iteration brings
                    a different context to first_context position */
                this_context = this_client->first_context;
                rundown_elt = (rpc_ss_rundown_list_elt *)
                                malloc(sizeof(rpc_ss_rundown_list_elt));
                if (rundown_elt == NULL)
                {
                    RPC_SS_THREADS_MUTEX_UNLOCK(&rpc_ss_context_table_mutex);
                    DPRINT(("Released context tables\n"));
		    /*
		     * rpc_m_ctxrundown_nomem
		     * "Out of memory while trying to run down contexts of client %x"
		     */
                    RPC_DCE_SVC_PRINTF ((
		        DCE_SVC(RPC__SVC_HANDLE, "%x"),
		        rpc_svc_libidl,
		        svc_c_sev_error,
		        rpc_m_ctxrundown_nomem,
		        this_client ));
                    return;
                }
                rundown_elt->rundown = this_context->rundown;
                rundown_elt->user_context = this_context->user_context;
                rundown_elt->next = rundown_list;
                rundown_list = rundown_elt;
                rpc_ss_lkddest_callee_context
                                    (&this_context->uuid,&close_client,&result);
            }
        }
    }
    RPC_SS_THREADS_MUTEX_UNLOCK(&rpc_ss_context_table_mutex);
    DPRINT(("Released context tables\n"));
    while (rundown_list != NULL)
    {
        if (rundown_list->rundown != NULL)
        {
            DCETHREAD_TRY
            (*(rundown_list->rundown))(rundown_list->user_context);
            DCETHREAD_CATCH_ALL(caught)
		/*
		 * rpc_m_ctxrundown_exc
		 * "Exception in routine at %x, running down context %x of client %x"
		 */
                RPC_DCE_SVC_PRINTF ((
		    DCE_SVC(RPC__SVC_HANDLE, "%x%x%x"),
		    rpc_svc_libidl,
		    svc_c_sev_error,
		    rpc_m_ctxrundown_exc,
                    rundown_list->rundown,
		    rundown_list->user_context,
		    this_client ));
            DCETHREAD_ENDTRY
        }
        rundown_elt = rundown_list;
        rundown_list = rundown_list->next;
        free(rundown_elt);
    }