genericopenlibs/openenvcore/libpthread/src/pthread_exit.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Name     : pthread_exit.cpp
       
    15 // Part of  : PThread library
       
    16 // pthread_exit call is implemented.
       
    17 // Version:
       
    18 //
       
    19 
       
    20 
       
    21 
       
    22 #include <pthread.h>
       
    23 #include <stdio.h>
       
    24 #include <stdlib.h>
       
    25 #include <errno.h>
       
    26 #include <e32base.h>
       
    27 #include "threadglobals.h"
       
    28 #include "pthreadmisc.h"
       
    29 
       
    30 #define THREAD_COUNT_ONE 1
       
    31 
       
    32 
       
    33 EXPORT_C void pthread_exit(void *retValPtr)
       
    34 {
       
    35     _global_data_t *glbPtr;
       
    36     _pthread_node_t *tempPtr;
       
    37     _pthread_node_t *selfNodePtr;
       
    38         
       
    39     THR_PRINTF("[pthread] Begin pthread_exit\n");
       
    40     
       
    41     //Get the TLS value (self node pointer)
       
    42     selfNodePtr = (_pthread_node_t*) _pthread_getTls();
       
    43     //coverity[var_compare_op]
       
    44     if (NULL == selfNodePtr)    // This should never happen
       
    45     {
       
    46         THR_PRINTF("[pthread] FATAL :TLS is not initialized \n");
       
    47         THR_PRINTF("[pthread] Terminating the process\n");
       
    48         RProcess rp;
       
    49         rp.Kill(0);                // Terminate the process
       
    50     }
       
    51 
       
    52     //coverity[var_deref_op]
       
    53     if (_MAIN_THREAD == selfNodePtr->mainFlag)
       
    54     {
       
    55     	// Make the main thread non critical, so that the process does not 
       
    56     	// terminate, after main exits with pthread_exit()
       
    57     	User::SetCritical(User::ENotCritical);
       
    58     }
       
    59     
       
    60     glbPtr = selfNodePtr->glbDataPtr;  // point to global struct
       
    61     
       
    62     // Call destructors for TLS keys
       
    63     _pthread_destroyKeys(glbPtr,selfNodePtr);
       
    64     
       
    65     glbPtr->lockThreadTable.Wait();    // Acquire the thread table lock
       
    66     
       
    67     // Traverse through the list, till destination node is reached
       
    68     for (tempPtr = glbPtr->start; 
       
    69          ((tempPtr != selfNodePtr) && (tempPtr != NULL)); 
       
    70          tempPtr = tempPtr->next)
       
    71     {
       
    72         ;             // Empty loop 
       
    73     }
       
    74     
       
    75     if (NULL == tempPtr)              // Not found; 
       
    76     {
       
    77         THR_PRINTF("[pthread] FATAL :thread node not found \n");
       
    78         THR_PRINTF("[pthread] Terminating the process\n");
       
    79         RProcess rp;
       
    80         rp.Kill(0);                // Terminate the process
       
    81     }
       
    82     
       
    83     selfNodePtr->lockNode.Wait(); // Acquire the node lock 
       
    84 
       
    85     selfNodePtr->returnValue = retValPtr;  // Store the return val
       
    86     
       
    87     //added to solve memoryleak
       
    88     CTrapCleanup* pCleanup = (CTrapCleanup*)selfNodePtr->cleanStackPtr; 
       
    89     selfNodePtr->cleanStackPtr = NULL;    
       
    90     
       
    91     // Check the thread count and if it becoming zero then terminate process
       
    92     --(glbPtr->threadCount); // Update the thread count
       
    93     if (THREAD_COUNT_ZERO == glbPtr->threadCount)
       
    94     {
       
    95 		THR_PRINTF("[pthread] Terminating the process\n");
       
    96 		// Terminate the process by calling exit(0)
       
    97 		exit(0);
       
    98         /*
       
    99 		RProcess rp;
       
   100         rp.Kill(0);*/
       
   101 
       
   102         // Free the cleanup stack
       
   103         delete pCleanup;
       
   104     }
       
   105 
       
   106     if (PTHREAD_CREATE_DETACHED == selfNodePtr->detachState)
       
   107     {
       
   108         // Delete the Node;
       
   109         _pthread_deleteNode(selfNodePtr, glbPtr, NULL);
       
   110         // It also unlocks the node aswell unlocks the thread table lock
       
   111     }
       
   112     else
       
   113     {
       
   114         selfNodePtr->threadState = _THREAD_ZOMBIE;
       
   115         selfNodePtr->lockNode.Signal();    // Unlock the node
       
   116         
       
   117         glbPtr->lockThreadTable.Signal();  // release thread table lock
       
   118     }
       
   119     
       
   120     // Free the cleanup stack
       
   121     delete pCleanup;    
       
   122     
       
   123     //Terminate the current thread
       
   124     THR_PRINTF("[pthread] Terminating the current thread\n");
       
   125     /*
       
   126     
       
   127       "RThread.Kill  cannot be used to terminate the thread in question because the thread uses a shared heap and 
       
   128      RThread.Kill  will cause the internal array used for thread-local storage(TLS) to be leaked only on specific ARM platforms
       
   129      which implement the CP15 feature."
       
   130      */
       
   131     User::Exit(0);
       
   132         
       
   133 
       
   134 }
       
   135 
       
   136 // End of file