Logo Search packages:      
Sourcecode: pcsc-lite version File versions  Download package

LONG CreateContextThread ( uint32_t *  pdwClientID )

Creates threads to handle messages received from Clients.

Parameters:
[in]pdwClientIDConnection ID used to reference the Client.
Returns:
Error code.
Return values:
SCARD_S_SUCCESSSuccess.
SCARD_F_INTERNAL_ERRORExceded the maximum number of simultaneous Application Contexts.
SCARD_E_NO_MEMORYError creating the Context Thread.

Definition at line 144 of file winscard_svc.c.

References AutoExit, _psContext::cardsList_lock, contextsList_lock, _psContext::dwClientID, _psContext::pthThread, SCARD_E_NO_MEMORY, and SCARD_S_SUCCESS.

Referenced by SVCServiceRunLoop().

{
      int rv;
      int lrv;
      int listSize;
      SCONTEXT * newContext = NULL;

      (void)pthread_mutex_lock(&contextsList_lock);
      listSize = list_size(&contextsList);
      (void)pthread_mutex_unlock(&contextsList_lock);

      if (listSize >= contextMaxThreadCounter)
      {
            Log2(PCSC_LOG_CRITICAL, "Too many context running: %d", listSize);
            goto error;
      }

      /* Create the context for this thread. */
      newContext = malloc(sizeof(*newContext));
      if (NULL == newContext)
      {
            Log1(PCSC_LOG_CRITICAL, "Could not allocate new context");
            goto error;
      }
      memset(newContext, 0, sizeof(*newContext));

      newContext->dwClientID = *pdwClientID;

      /* Initialise the list of card contexts */
      lrv = list_init(&(newContext->cardsList));
      if (lrv < 0)
      {
            Log2(PCSC_LOG_CRITICAL, "list_init failed with return value: %d", lrv);
            goto error;
      }

      /* request to store copies, and provide the metric function */
      list_attributes_copy(&(newContext->cardsList), list_meter_int32_t, 1);

      /* Adding a comparator
       * The stored type is SCARDHANDLE (long) but has only 32 bits
       * usefull even on a 64-bit CPU since the API between pcscd and
       * libpcscliter uses "int32_t hCard;"
       */
      lrv = list_attributes_comparator(&(newContext->cardsList),
            list_comparator_int32_t);
      if (lrv != 0)
      {
            Log2(PCSC_LOG_CRITICAL,
                  "list_attributes_comparator failed with return value: %d", lrv);
            list_destroy(&(newContext->cardsList));
            goto error;
      }

      (void)pthread_mutex_init(&newContext->cardsList_lock, NULL);

      (void)pthread_mutex_lock(&contextsList_lock);
      lrv = list_append(&contextsList, newContext);
      (void)pthread_mutex_unlock(&contextsList_lock);
      if (lrv < 0)
      {
            Log2(PCSC_LOG_CRITICAL, "list_append failed with return value: %d",
                  lrv);
            list_destroy(&(newContext->cardsList));
            goto error;
      }

      rv = ThreadCreate(&(newContext->pthThread), THREAD_ATTR_DETACHED,
            (PCSCLITE_THREAD_FUNCTION( )) ContextThread, (LPVOID) newContext);
      if (rv)
      {
            int lrv2;

            Log2(PCSC_LOG_CRITICAL, "ThreadCreate failed: %s", strerror(rv));
            (void)pthread_mutex_lock(&contextsList_lock);
            lrv2 = list_delete(&contextsList, newContext);
            (void)pthread_mutex_unlock(&contextsList_lock);
            if (lrv2 < 0)
                  Log2(PCSC_LOG_CRITICAL, "list_delete failed with error %d", lrv2);
            list_destroy(&(newContext->cardsList));
            goto error;
      }

      /* disable any suicide alarm */
      if (AutoExit)
            alarm(0);

      return SCARD_S_SUCCESS;

error:
      if (newContext)
            free(newContext);
      (void)close(*pdwClientID);
      return SCARD_E_NO_MEMORY;
}

Here is the caller graph for this function:


Generated by  Doxygen 1.6.0   Back to index