Esempio n. 1
0
PRIVATE dce_pointer_t rpc__list_element_alloc
(
    rpc_list_desc_p_t       list_desc,
    boolean32               block
)
{
    volatile dce_pointer_t  element = NULL;
    unsigned32          wait_cnt;
    struct timespec     delta;
    struct timespec     abstime;

    RPC_LOG_LIST_ELT_ALLOC_NTR;

    for (wait_cnt = 0;
         wait_cnt < rpc_g_lookaside_rcb.max_wait_times;
         wait_cnt++)
    {
        /*
         * Acquire the global resource control lock for all lookaside
         * lists if the caller doesn't have their own lock.
         */
        if (list_desc->use_global_mutex)
        {
            RPC_MUTEX_LOCK (rpc_g_lookaside_rcb.res_lock);
        }

        /*
         * Try allocating a structure off the lookaside list given.
         */
        if (list_desc->cur_size > 0)
        {
#define DEBUG 1
#ifdef DEBUG
            if (list_desc->list_head.next == NULL)
            {
                /*
                 * rpc_m_lookaside_corrupt
                 * "(%s) Lookaside list is corrupted"
                 */
                rpc_dce_svc_printf (
                    __FILE__, __LINE__,
                    "%s",
                    rpc_svc_general,
                    svc_c_sev_fatal | svc_c_action_abort,
                    rpc_m_lookaside_corrupt,
                    "rpc__list_element_alloc" );
            }
#endif
            list_desc->cur_size--;
            RPC_LIST_REMOVE_HEAD (list_desc->list_head, element, dce_pointer_t);

            /*
             * Release the global resource control lock for all lookaside
             * lists if the caller doesn't have their own lock.
             */
            if (list_desc->use_global_mutex)
            {
                RPC_MUTEX_UNLOCK (rpc_g_lookaside_rcb.res_lock);
            }
            break;
        }
        else
        {
            /*
             * Release the global resource control lock if the
             * caller doesn't have their own lock for all lookaside lists
             * since the structure was available on the lookaside list.
             *
             * We do it now because allocating an element from heap is a relatively
             * time consuming operation.
             */
            if (list_desc->use_global_mutex)
            {
                RPC_MUTEX_UNLOCK (rpc_g_lookaside_rcb.res_lock);
            }

            /*
             * The lookaside list is empty. Try and allocate from
             * heap.
             */
            RPC_MEM_ALLOC (element,
                           dce_pointer_t,
                           list_desc->element_size,
                           list_desc->element_type,
                           RPC_C_MEM_NOWAIT);

            if (element == NULL)
            {
                /*
                 * The heap allocate failed. If the caller indicated
                 * that we should not block return right now.
                 */
                if (block == false)
                {
                    break;
                }

                delta.tv_sec = rpc_g_lookaside_rcb.wait_time;
                delta.tv_nsec = 0;
                dcethread_get_expiration (&delta, &abstime);

                /*
                 * If we are using the global lookaside list lock
                 * then reaquire the global lookaside list lock and
                 * wait on the global lookaside list condition
                 * variable otherwise use the caller's mutex and
                 * condition variable.
                 */
                if (list_desc->use_global_mutex)
                {
                    RPC_MUTEX_LOCK (rpc_g_lookaside_rcb.res_lock);
                    RPC_COND_TIMED_WAIT (rpc_g_lookaside_rcb.wait_flg,
                                         rpc_g_lookaside_rcb.res_lock,
                                         &abstime);
                    RPC_MUTEX_UNLOCK (rpc_g_lookaside_rcb.res_lock);
                }
                else
                {
                    RPC_COND_TIMED_WAIT (*list_desc->cond,
                                         *list_desc->mutex,
                                         &abstime);
                }

                /*
                 * Try to allocate the structure again.
                 */
                continue;
            }
            else
            {
                /*
                 * The RPC_MEM_ALLOC succeeded. If an alloc routine
                 * was specified when the lookaside list was inited
                 * call it now.
                 */
                if (list_desc->alloc_rtn != NULL)
                {
                    /*
                     * Catch any exceptions which may occur in the
                     * list-specific alloc routine. Any exceptions
                     * will be caught and the memory will be freed.
                     */
                    DCETHREAD_TRY
                    {
                        (*list_desc->alloc_rtn) (element);
                    }
                    DCETHREAD_CATCH_ALL(THIS_CATCH)
                    {
                        RPC_MEM_FREE (element, list_desc->element_type);
                        element = NULL;
                        /*
                         * rpc_m_call_failed_no_status
                         * "%s failed"
                         */
                        rpc_dce_svc_printf (
                            __FILE__, __LINE__,
                            "%s",
                            rpc_svc_general,
                            svc_c_sev_fatal | svc_c_action_abort,
                            rpc_m_call_failed_no_status,
                            "rpc__list_element_alloc/(*list_desc->alloc_rtn)(element)" );
                    }
                    DCETHREAD_ENDTRY
                }
                break;
            }
        }
    }
Esempio n. 2
0
INTERNAL void network_monitor_liveness(void)
{
    rpc_dg_client_rep_p_t client;
    unsigned32 i;
    struct timespec next_ts;

    RPC_DBG_PRINTF(rpc_e_dbg_conv_thread, 1, 
                   ("(network_monitor_liveness) starting up...\n"));

    RPC_MUTEX_LOCK(monitor_mutex);

    while (stop_monitor == false)
    {
        /*
         * Awake every 60 seconds.
         */
        rpc__clock_timespec(rpc__clock_stamp()+60, &next_ts);

        RPC_COND_TIMED_WAIT(monitor_cond, monitor_mutex, &next_ts);
        if (stop_monitor == true)
            break;

        for (i = 0; i < CLIENT_TABLE_SIZE; i++)
        {                                     
            client = client_table[i];
    
            while (client != NULL && active_monitors != 0)
            {      
                if (client->rundown != NULL &&
                    rpc__clock_aged(client->last_update, 
                                    RPC_CLOCK_SEC(LIVE_TIMEOUT_INTERVAL)))
                {                 
                    /*
                     * If the timer has expired, call the rundown routine.
                     * Stop monitoring the client handle by setting its rundown
                     * routine pointer to NULL.
                     */
    
                    RPC_DBG_PRINTF(rpc_e_dbg_general, 3, 
                        ("(network_monitor_liveness_timer) Calling rundown function\n"));
                            
                    RPC_MUTEX_UNLOCK(monitor_mutex);
                    (*client->rundown)((rpc_client_handle_t)client);
                    RPC_MUTEX_LOCK(monitor_mutex);

                    /*
                     * The monitor is no longer active.
                     */
                    client->rundown = NULL;
                    active_monitors--;
                }
                client = client->next;
            }

            if (active_monitors == 0)
            {
                /*
                 * While we were executing the rundown function and opened the
                 * mutex, the fork handler might try to stop us.
                 */
                if (stop_monitor == true)
                    break;
                /*
                 * Nothing left to monitor, so terminate the thread.
                 */
                dcethread_detach_throw(monitor_task);
                monitor_running = false;
                RPC_DBG_PRINTF(rpc_e_dbg_conv_thread, 1, 
                    ("(network_monitor_liveness) shutting down (no active)...\n"));
                RPC_MUTEX_UNLOCK(monitor_mutex);
                return;
            }
        }
    }
    RPC_DBG_PRINTF(rpc_e_dbg_conv_thread, 1, 
                   ("(network_monitor_liveness) shutting down...\n"));

    RPC_MUTEX_UNLOCK(monitor_mutex);
}