コード例 #1
0
/*! \internal
  \brief Uninitialize a plugin

  In addition to terminating the thread, and removing p from the
  linked list and hashtable, it also frees up p.
   
  \note Should only be called from the context of the registrar thread. */
void kmmint_exit_plugin(kmm_plugin_i * p) {
    int np;
    khm_boolean release_plugin = TRUE;

    if(p->state == KMM_PLUGIN_STATE_RUNNING ||
       p->state == KMM_PLUGIN_STATE_INIT) {

        kmq_post_thread_quit_message(p->tid_thread, 0, NULL);
        /* when we post the quit message to the plugin thread, the plugin
           broker terminates the plugin and posts a EXIT_PLUGIN message,
           which calls this function again.  We just exit here because
           the EXIT_PLUGIN message will end up calling us again momentarily */
        return;

    }

    if(p->ht_thread) {
        /* wait for the thread to terminate */
        WaitForSingleObject(p->ht_thread, INFINITE);
        p->ht_thread = NULL;
    }

    EnterCriticalSection(&cs_kmm);

    /* undo reference count done in kmmint_init_plugin() */
    if(p->flags & KMM_PLUGIN_FLAG_IN_MODCOUNT) {

        np = --(p->module->plugin_count);
        p->flags &= ~KMM_PLUGIN_FLAG_IN_MODCOUNT;

    } else {
        /* the plugin was not included in the module's plugin_count.
           We can't base a decision to unload the module based on this
           plugin exiting. */
        np = TRUE;
    }

    /* The plugin is in an error state.  We need to keep the plugin
       record intact so that the failure information is kept around.
       Also, we shouldn't release the plugin if it appears that
       kmmint_init_plugin() was never called for it. */
    if (p->state < KMM_PLUGIN_STATE_HOLD) {
        release_plugin = FALSE;
    }

    LeaveCriticalSection(&cs_kmm);

    if(!np) {
        /*  if this is the last plugin to exit, then notify the
            registrar that the module should be removed as well */
        kmm_hold_module(kmm_handle_from_module(p->module));
        kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, KMM_REG_EXIT_MODULE, (void *) p->module);
    }

    /* release the hold obtained in kmmint_init_plugin() */
    if (release_plugin)
        kmm_release_plugin(kmm_handle_from_plugin(p));
}
コード例 #2
0
ファイル: publisher.c プロジェクト: Brainiarc7/pbis
/*! \internal
    \note Obtains ::cs_kmq_global, ::cs_kmq_msg, ::cs_kmq_msg_ref, kmq_queue::cs
    */
KHMEXP khm_int32 KHMAPI
kmq_send_thread_quit_message(kmq_thread_id thread, khm_ui_4 uparam) {
    kmq_call c;
    khm_int32 rv = KHM_ERROR_SUCCESS;

    rv = kmq_post_thread_quit_message(thread, uparam, &c);
    if(KHM_FAILED(rv))
        return rv;

    rv = kmq_wait(c, INFINITE);

    kmq_free_call(c);

    return rv;
}
コード例 #3
0
ファイル: kmmmain.c プロジェクト: aosm/Kerberos
KHMEXP void KHMAPI kmm_exit(void)
{
    kmm_module_i * m;
    kmm_plugin_i * p;

    EnterCriticalSection(&cs_kmm);

    p = kmm_listed_plugins;
    while(p) {
        kmm_plugin_i * pn;

        pn = LNEXT(p);
        /* plugins that were never resolved should be kicked off the
           list.  Flipping the refcount will do that if no other
           references exist for the plugin.  The plugins that were
           waiting for unresolved dependencies will automatically get
           freed when the placeholders and other plugins get freed. */
        if(p->state == KMM_PLUGIN_STATE_PLACEHOLDER) {
            kmm_hold_plugin(kmm_handle_from_plugin(p));
            kmm_release_plugin(kmm_handle_from_plugin(p));
        }

        p = pn;
    }

    m = kmm_all_modules;
    while(m) {
        kmm_unload_module(kmm_handle_from_module(m));
        m = LNEXT(m);
    }

    LeaveCriticalSection(&cs_kmm);
    WaitForSingleObject(evt_exit, INFINITE);
    EnterCriticalSection(&cs_kmm);

    kmq_post_thread_quit_message(tid_registrar, 0, NULL);

    hash_del_hashtable(hash_plugins);
    hash_del_hashtable(hash_modules);

    LeaveCriticalSection(&cs_kmm);

    TlsFree(tls_kmm);

    tls_kmm = 0;
}