Exemplo n.º 1
0
void dec_nlm_client_ref_locked(state_nlm_client_t *pclient)
{
  bool_t remove = FALSE;
  char   str[HASHTABLE_DISPLAY_STRLEN];

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

  if(pclient->slc_refcount > 1)
    {
      pclient->slc_refcount--;

      LogFullDebug(COMPONENT_STATE,
                   "Decrement refcount NLM Client {%s}",
                   str);
    }
  else
    remove = TRUE;

  V(pclient->slc_mutex);

  if(remove)
    {
      hash_buffer_t buffkey, old_key, old_value;

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

      switch(HashTable_DelRef(ht_nlm_client, &buffkey, &old_key, &old_value, Hash_dec_nlm_client_ref))
        {
          case HASHTABLE_SUCCESS:
            LogFullDebug(COMPONENT_STATE,
                         "Free NLM Client {%s} size %llx",
                         str, (unsigned long long) old_value.len);
            if(pclient->slc_callback_clnt != NULL)
              Clnt_destroy(pclient->slc_callback_clnt);
            dec_nsm_client_ref(pclient->slc_nsm_client);
            if(isFullDebug(COMPONENT_MEMLEAKS))
              {
                memset(old_key.pdata, 0, old_key.len);
                memset(old_value.pdata, 0, old_value.len);
              }
            Mem_Free(old_key.pdata);
            Mem_Free(old_value.pdata);
            break;

          case HASHTABLE_NOT_DELETED:
            /* ref count didn't end up at 0, don't free. */
            LogDebug(COMPONENT_STATE,
                     "HashTable_DelRef didn't reduce refcount to 0 for NLM Client {%s}",
                     str);
            break;

          default:
            /* some problem occurred */
            LogDebug(COMPONENT_STATE,
                     "HashTable_DelRef failed for NLM Client {%s}",
                     str);
            break;
        }
    }
}
Exemplo n.º 2
0
/* Client routine  to send the asynchrnous response, key is used to wait for a response */
int nlm_send_async(int                  proc,
                   state_nlm_client_t * host,
                   void               * inarg,
                   void               * key)
{
  struct timeval  tout = { 0, 10 };
  int             retval, retry;
  struct timeval  start, now;
  struct timespec timeout;

  for(retry = 1; retry <= MAX_ASYNC_RETRY; retry++)
    {
      if(host->slc_callback_clnt == NULL)
        {
          LogFullDebug(COMPONENT_NLM,
                       "Clnt_create %s",
                       host->slc_nsm_client->ssc_nlm_caller_name);

          host->slc_callback_clnt = Clnt_create(host->slc_nsm_client->ssc_nlm_caller_name,
                                                NLMPROG,
                                                NLM4_VERS,
                                                (char *)xprt_type_to_str(host->slc_client_type));

          if(host->slc_callback_clnt == NULL)
            {
              LogMajor(COMPONENT_NLM,
                       "Cannot create NLM async %s connection to client %s",
                       xprt_type_to_str(host->slc_client_type),
                       host->slc_nsm_client->ssc_nlm_caller_name);
              return -1;
            }
        }

      pthread_mutex_lock(&nlm_async_resp_mutex);
      resp_key = key;
      pthread_mutex_unlock(&nlm_async_resp_mutex);

      LogFullDebug(COMPONENT_NLM, "About to make clnt_call");
      retval = clnt_call(host->slc_callback_clnt,
                         proc,
                         nlm_reply_proc[proc],
                         inarg,
                         (xdrproc_t) xdr_void,
                         NULL,
                         tout);
      LogFullDebug(COMPONENT_NLM, "Done with clnt_call");

      if(retval == RPC_TIMEDOUT || retval == RPC_SUCCESS)
        {
          retval = RPC_SUCCESS;
          break;
        }

      LogDebug(COMPONENT_NLM,
               "NLM async Client procedure call %d failed with return code %d %s",
               proc, retval, clnt_sperror(host->slc_callback_clnt, ""));

      Clnt_destroy(host->slc_callback_clnt);
      host->slc_callback_clnt = NULL;

      if(retry == MAX_ASYNC_RETRY)
        {
          LogMajor(COMPONENT_NLM,
                   "NLM async Client exceeded retry count %d",
                   MAX_ASYNC_RETRY);
          pthread_mutex_lock(&nlm_async_resp_mutex);
          resp_key = NULL;
          pthread_mutex_unlock(&nlm_async_resp_mutex);
          return retval;
        }
    }

  pthread_mutex_lock(&nlm_async_resp_mutex);
  if(resp_key != NULL)
    {
      /* Wait for 5 seconds or a signal */
      gettimeofday(&start, NULL);
      gettimeofday(&now, NULL);
      timeout.tv_sec = 5 + start.tv_sec;
      timeout.tv_nsec = 0;
      LogFullDebug(COMPONENT_NLM,
                   "About to wait for signal for key %p",
                   resp_key);
      while(resp_key != NULL && now.tv_sec < (start.tv_sec + 5))
        {
          int rc = pthread_cond_timedwait(&nlm_async_resp_cond, &nlm_async_resp_mutex, &timeout);
          LogFullDebug(COMPONENT_NLM,
                       "pthread_cond_timedwait returned %d", rc);
          gettimeofday(&now, NULL);
        }
      LogFullDebug(COMPONENT_NLM, "Done waiting");
    }
  pthread_mutex_unlock(&nlm_async_resp_mutex);

  return retval;
}