int32_t dec_session_ref(nfs41_session_t *session)
{
    int i;
    int32_t refcnt = atomic_dec_int32_t(&session->refcount);

    if (refcnt == 0) {

        /* Unlink the session from the client's list of
           sessions */
        PTHREAD_MUTEX_lock(&session->clientid_record->cid_mutex);
        glist_del(&session->session_link);
        PTHREAD_MUTEX_unlock(&session->clientid_record->cid_mutex);

        /* Decrement our reference to the clientid record */
        dec_client_id_ref(session->clientid_record);
        /* Destroy this session's mutexes and condition variable */

        for (i = 0; i < NFS41_NB_SLOTS; i++)
            PTHREAD_MUTEX_destroy(&session->slots[i].lock);

        PTHREAD_COND_destroy(&session->cb_cond);
        PTHREAD_MUTEX_destroy(&session->cb_mutex);

        /* Destroy the session's back channel (if any) */
        if (session->flags & session_bc_up)
            nfs_rpc_destroy_chan(&session->cb_chan);

        /* Free the memory for the session */
        pool_free(nfs41_session_pool, session);
    }

    return refcnt;
}
Esempio n. 2
0
void dec_nlm_client_ref(state_nlm_client_t *pclient)
{
  char              str[HASHTABLE_DISPLAY_STRLEN];
  struct hash_latch latch;
  hash_error_t      rc;
  hash_buffer_t     buffkey;
  hash_buffer_t     old_value;
  hash_buffer_t     old_key;
  int32_t           refcount;

  if(isDebug(COMPONENT_STATE))
    display_nlm_client(pclient, str);

  refcount = atomic_dec_int32_t(&pclient->slc_refcount);

  if(refcount > 0)
    {
      LogFullDebug(COMPONENT_STATE,
                   "Decrement refcount now=%"PRId32" {%s}",
                   refcount, str);

      return;
    }

  LogFullDebug(COMPONENT_STATE,
               "Try to remove {%s}",
               str);

  buffkey.pdata = pclient;
  buffkey.len   = sizeof(*pclient);

  /* Get the hash table entry and hold latch */
  rc = HashTable_GetLatch(ht_nlm_client,
                          &buffkey,
                          &old_value,
                          TRUE,
                          &latch);

  if(rc != HASHTABLE_SUCCESS)
    {
      if(rc == HASHTABLE_ERROR_NO_SUCH_KEY)
        HashTable_ReleaseLatched(ht_nlm_client, &latch);

      display_nlm_client(pclient, str);

      LogCrit(COMPONENT_STATE,
              "Error %s, could not find {%s}",
              hash_table_err_to_str(rc), str);

      return;
    }

  refcount = atomic_fetch_int32_t(&pclient->slc_refcount);

  if(refcount > 0)
    {
      LogDebug(COMPONENT_STATE,
               "Did not release refcount now=%"PRId32" {%s}",
               refcount, str);

      HashTable_ReleaseLatched(ht_nlm_client, &latch);

      return;
    }

  /* use the key to delete the entry */
  rc = HashTable_DeleteLatched(ht_nlm_client,
                               &buffkey,
                               &latch,
                               &old_key,
                               &old_value);

  if(rc != HASHTABLE_SUCCESS)
    {
      if(rc == HASHTABLE_ERROR_NO_SUCH_KEY)
        HashTable_ReleaseLatched(ht_nlm_client, &latch);

      display_nlm_client(pclient, str);

      LogCrit(COMPONENT_STATE,
              "Error %s, could not remove {%s}",
              hash_table_err_to_str(rc), str);

      return;
    }

  LogFullDebug(COMPONENT_STATE,
               "Free {%s}",
               str);

  free_nlm_client(old_value.pdata);
}
Esempio n. 3
0
/**
 * @brief Relinquish a reference on an NSM client
 *
 * @param[in] client The client to release
 */
void dec_nsm_client_ref(state_nsm_client_t *client)
{
	char str[LOG_BUFF_LEN];
	struct display_buffer dspbuf = {sizeof(str), str, str};
	bool str_valid = false;
	struct hash_latch latch;
	hash_error_t rc;
	struct gsh_buffdesc buffkey;
	struct gsh_buffdesc old_value;
	struct gsh_buffdesc old_key;
	int32_t refcount;

	if (isDebug(COMPONENT_STATE)) {
		display_nsm_client(&dspbuf, client);
		str_valid = true;
	}

	refcount = atomic_dec_int32_t(&client->ssc_refcount);

	if (refcount > 0) {
		if (str_valid)
			LogFullDebug(COMPONENT_STATE,
				     "Decrement refcount now=%" PRId32 " {%s}",
				     refcount, str);

		return;
	}

	if (str_valid)
		LogFullDebug(COMPONENT_STATE, "Try to remove {%s}", str);

	buffkey.addr = client;
	buffkey.len = sizeof(*client);

	/* Get the hash table entry and hold latch */
	rc = hashtable_getlatch(ht_nsm_client, &buffkey, &old_value, true,
				&latch);

	if (rc != HASHTABLE_SUCCESS) {
		if (rc == HASHTABLE_ERROR_NO_SUCH_KEY)
			hashtable_releaselatched(ht_nsm_client, &latch);

		if (!str_valid)
			display_nsm_client(&dspbuf, client);

		LogCrit(COMPONENT_STATE, "Error %s, could not find {%s}",
			hash_table_err_to_str(rc), str);

		return;
	}

	refcount = atomic_fetch_int32_t(&client->ssc_refcount);

	if (refcount > 0) {
		if (str_valid)
			LogDebug(COMPONENT_STATE,
				 "Did not release refcount now=%"PRId32" {%s}",
				 refcount, str);

		hashtable_releaselatched(ht_nsm_client, &latch);

		return;
	}

	/* use the key to delete the entry */
	rc = hashtable_deletelatched(ht_nsm_client, &buffkey, &latch, &old_key,
				     &old_value);

	if (rc != HASHTABLE_SUCCESS) {
		if (rc == HASHTABLE_ERROR_NO_SUCH_KEY)
			hashtable_releaselatched(ht_nsm_client, &latch);

		if (!str_valid)
			display_nsm_client(&dspbuf, client);

		LogCrit(COMPONENT_STATE, "Error %s, could not remove {%s}",
			hash_table_err_to_str(rc), str);

		return;
	}

	LogFullDebug(COMPONENT_STATE, "Free {%s}", str);

	nsm_unmonitor(old_value.addr);
	free_nsm_client(old_value.addr);
}