diff -r 000000000000 -r e4d67989cc36 genericopenlibs/openenvcore/libpthread/src/pthread_key_delete.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/genericopenlibs/openenvcore/libpthread/src/pthread_key_delete.cpp Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,132 @@ +// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Name : pthread_key_delete.cpp +// Part of : PThread library +// pthread_key_delete call is implemented. +// Version: +// + + + +#include +#include +#include "threadglobals.h" +#include "pthreadmisc.h" + +static int _deleteKeyInAllThreads(_global_data_t *glbPtr, int keyNumber) +{ + _pthread_node_t *temp; + _pkey_node_t *tlsPtr; + _pkey_node_t *prevTlsPtr; + + //For all threads + for (temp = glbPtr->start; temp != NULL; temp = temp->next) + { + // Lock the TCB + temp->lockNode.Wait(); + + // Delete in a sorted list + for (tlsPtr = temp->tlsHead, prevTlsPtr = NULL; + tlsPtr != NULL; + prevTlsPtr = tlsPtr,tlsPtr = tlsPtr->next) + { + if (tlsPtr->keyNumber == keyNumber) + { + if (temp->tlsHead == tlsPtr) //first node case + { + temp->tlsHead = tlsPtr->next; + delete tlsPtr; + break; // Inner loop + } + else + { + prevTlsPtr->next = tlsPtr->next; + delete tlsPtr; + break; //Inner loop + } + + } + + } // Inner for loop end... + + if (tlsPtr == NULL) // Means not found + { + // This should never happen; key to be deleted not exists + temp->lockNode.Signal(); + User::Panic(_L("Invalid Key"),0); + return -1; + } + + // Unlock TCB node + temp->lockNode.Signal(); + } // end of outer for loop + + return 0; +} + +EXPORT_C int pthread_key_delete(pthread_key_t key) +{ + _global_data_t *glbPtr; + _pthread_node_t *selfNodePtr; + + THR_PRINTF("[pthread] Begin pthread_key_delete\n"); + + if (key >= PTHREAD_KEYS_MAX) + { + THR_PRINTF("[pthread] End pthread_key_delete\n"); + return EINVAL; + } + + //Get the TLS value (self node pointer) + selfNodePtr = (_pthread_node_t*) _pthread_getTls(); + //coverity[var_compare_op] + if (NULL == selfNodePtr) // This should never happen + { + THR_PRINTF("[pthread] FATAL :TLS is not initialized \n"); + THR_PRINTF("[pthread] Terminating the process\n"); + RProcess rp; + rp.Kill(0); // Terminate the process + } + + //coverity[var_deref_op] + glbPtr = selfNodePtr->glbDataPtr; // point to global struct + glbPtr->lockThreadTable.Wait(); // Acquire the thread table lock + + int idx; + idx = key / 32; + + int bitPos; + bitPos = key % 32; + + if (((glbPtr->statusflag[idx]) & (0x1<lockThreadTable.Signal(); // release thread table lock + return EINVAL; + } + + glbPtr->statusflag[idx] &= ~(0x1<pthread_key_list[key].destr = NULL; + + // Delete the key in all the threads + _deleteKeyInAllThreads(glbPtr, key); + + glbPtr->lockThreadTable.Signal(); // release thread table lock + + THR_PRINTF("[pthread] End pthread_key_delete\n"); + return 0; + +} + +// End of file