예제 #1
0
    void SharedContents::Cleanup()
    {
        Assert(refCount == 0);
        buffer = nullptr;
        bufferLength = 0;
#if DBG
        if (allowedAgents != nullptr)
        {
            HeapDelete(allowedAgents);
            allowedAgents = nullptr;
        }
#endif

        if (indexToWaiterList != nullptr)
        {
            indexToWaiterList->Map([](uint index, WaiterList *waiters) {
                if (waiters != nullptr)
                {
                    waiters->Cleanup();
                    HeapDelete(waiters);
                    waiters = nullptr;
                }
            });

            HeapDelete(indexToWaiterList);
            indexToWaiterList = nullptr;
        }
    }
예제 #2
0
    void SharedContents::Cleanup()
    {
        Assert(refCount == 0);
        buffer = nullptr;
        bufferLength = 0;
#if DBG
        {
            AutoCriticalSection autoCS(&csAgent);
            if (allowedAgents != nullptr)
            {
                HeapDelete(allowedAgents);
                allowedAgents = nullptr;
            }
        }
#endif

        if (indexToWaiterList != nullptr)
        {
            // TODO: the map should be empty here?
            // or we need to wake all the waiters from current context?
            indexToWaiterList->Map([](uint index, WaiterList *waiters)
            {
                if (waiters != nullptr)
                {
                    waiters->Cleanup();
                    HeapDelete(waiters);
                    waiters = nullptr;
                }
            });

            HeapDelete(indexToWaiterList);
            indexToWaiterList = nullptr;
        }
    }
예제 #3
0
JsrtRuntime::~JsrtRuntime()
{
    HeapDelete(allocationPolicyManager);
    if (this->jsrtDebugManager != nullptr)
    {
        HeapDelete(this->jsrtDebugManager);
        this->jsrtDebugManager = nullptr;
    }
}
예제 #4
0
JsrtRuntime::~JsrtRuntime()
{
    HeapDelete(allocationPolicyManager);
#ifdef ENABLE_SCRIPT_DEBUGGING
    if (this->jsrtDebugManager != nullptr)
    {
        HeapDelete(this->jsrtDebugManager);
        this->jsrtDebugManager = nullptr;
    }
#endif
}
예제 #5
0
ServerScriptContext::~ServerScriptContext()
{
    HeapDelete(m_domFastPathHelperMap);
    m_moduleRecords.Map([](uint, Js::ServerSourceTextModuleRecord* record)
    {
        HeapDelete(record);
    });

#ifdef PROFILE_EXEC
    if (m_codeGenProfiler)
    {
        HeapDelete(m_codeGenProfiler);
    }
#endif
}
예제 #6
0
CodeGenWorkItem::~CodeGenWorkItem()
{
    if(queuedFullJitWorkItem)
    {
        HeapDelete(queuedFullJitWorkItem);
    }
}
예제 #7
0
 ~AutoCleanupSharedContents()
 {
     if (!allocationCompleted)
     {
         HeapDelete(sharedContents);
     }
 }
예제 #8
0
 void WaiterList::Cleanup()
 {
     if (m_waiters != nullptr)
     {
         HeapDelete(m_waiters);
         m_waiters = nullptr;
     }
 }
예제 #9
0
void JsrtRuntime::DeleteJsrtDebugManager()
{
    if (this->jsrtDebugManager != nullptr)
    {
        HeapDelete(this->jsrtDebugManager);
        this->jsrtDebugManager = nullptr;
    }
}
void ServerThreadContext::Release()
{
    InterlockedExchangeSubtract(&m_refCount, (uint)1);
    if (m_isClosed && m_refCount == 0)
    {
        HeapDelete(this);
    }
}
ServerThreadContext::~ServerThreadContext()
{
    processContext->Release();
    if (this->m_numericPropertyBV != nullptr)
    {
        HeapDelete(m_numericPropertyBV);
        this->m_numericPropertyBV = nullptr;
    }

}
예제 #12
0
void ThreadContextTLSEntry::CleanupThread()
{
    ASSERT_ENTRY_INITIALIZED();
    ThreadContextTLSEntry* entry = ENTRY_FOR_CURRENT_THREAD();
    if (entry != NULL)
    {
        HeapDelete(entry);
        TlsSetValue(s_tlsSlot, NULL);
    }
}
예제 #13
0
파일: Heap.c 프로젝트: maodapeng/WDUtils
HEAP_DAT_T*
GetAndRemoveHeapTop(PHeap Heap)
{
	HEAP_DAT_T* ret;
	if (Heap->Used == 0)
		return NULL;
	ret = Heap->Entries[0]->pData;
	HeapDelete(Heap, 0);
	return ret;
}
void ThreadContextTLSEntry::CleanupThread()
{
    Assert(s_tlsSlot != TLS_OUT_OF_INDEXES);
    ThreadContextTLSEntry * entry = GetEntryForCurrentThread();

    if (entry != NULL)
    {
        HeapDelete(entry);
        TlsSetValue(s_tlsSlot, NULL);
    }
}
예제 #15
0
void XDataAllocator::ClearFreeList()
{
    XDataAllocationEntry* next = this->freeList;
    XDataAllocationEntry* entry;
    while(next)
    {
        entry = next;
        next = entry->next;
        HeapDelete(entry);
    }
    this->freeList = NULL;
}
void ThreadBoundThreadContextManager::DestroyAllContextsAndEntries()
{
    AutoCriticalSection lock(ThreadContext::GetCriticalSection());

    while (!entries.Empty())
    {
        ThreadContextTLSEntry * entry = entries.Head();
        ThreadContext * threadContext =  static_cast<ThreadContext *>(entry->GetThreadContext());

        entries.RemoveHead();

        if (threadContext != nullptr)
        {
#if DBG
            PageAllocator* pageAllocator = threadContext->GetPageAllocator();
            if (pageAllocator)
            {
                pageAllocator->SetConcurrentThreadId(::GetCurrentThreadId());
            }
#endif

            threadContext->ShutdownThreads();

            HeapDelete(threadContext);
        }

        ThreadContextTLSEntry::Delete(entry);
    }

#if ENABLE_BACKGROUND_JOB_PROCESSOR
    if (s_sharedJobProcessor != NULL)
    {
        s_sharedJobProcessor->Close();

        HeapDelete(s_sharedJobProcessor);
        s_sharedJobProcessor = NULL;
    }
#endif
}
예제 #17
0
파일: Jobs.cpp 프로젝트: dilijev/ChakraCore
    BackgroundJobProcessor::~BackgroundJobProcessor()
    {
        // This should appear to be called from the same thread from which this instance was created
        Assert(IsClosed());

        if (parallelThreadData)
        {
            for (unsigned int i = 0; i < this->threadCount; i++)
            {
                HeapDelete(parallelThreadData[i]);
            }
            HeapDeleteArray(this->maxThreadCount, parallelThreadData);
        }
    }
void ThreadContextManagerBase::ShutdownThreadContext(ThreadContext* threadContext)
{

#if DBG
    PageAllocator* pageAllocator = threadContext->GetPageAllocator();
    if (pageAllocator)
    {
        pageAllocator->SetConcurrentThreadId(::GetCurrentThreadId());
    }
#endif
    threadContext->ShutdownThreads();

    HeapDelete(threadContext);
}
예제 #19
0
void CodeGenWorkItem::OnRemoveFromJitQueue(NativeCodeGenerator* generator)
{
    // This is called from within the lock

    this->isInJitQueue = false;
    this->entryPointInfo->SetCodeGenPending();
    functionBody->GetScriptContext()->GetThreadContext()->UnregisterCodeGenRecyclableData(this->recyclableData);
    this->recyclableData = nullptr;

    if(IS_JS_ETW(EventEnabledJSCRIPT_FUNCTION_JIT_DEQUEUED()))
    {
        WCHAR displayNameBuffer[256];
        WCHAR* displayName = displayNameBuffer;
        size_t sizeInChars = this->GetDisplayName(displayName, 256);
        if(sizeInChars > 256)
        {
            displayName = HeapNewArray(WCHAR, sizeInChars);
            this->GetDisplayName(displayName, 256);
        }
        JS_ETW(EventWriteJSCRIPT_FUNCTION_JIT_DEQUEUED(
            this->GetFunctionNumber(),
            displayName,
            this->GetScriptContext(),
            this->GetInterpretedCount()));

        if(displayName != displayNameBuffer)
        {
            HeapDeleteArray(sizeInChars, displayName);
        }
    }

    if(this->Type() == JsLoopBodyWorkItemType)
    {
        // Go ahead and delete it and let it re-queue if more interpreting of the loop happens
        auto loopBodyWorkItem = static_cast<JsLoopBodyCodeGen*>(this);
        loopBodyWorkItem->loopHeader->ResetInterpreterCount();
        loopBodyWorkItem->GetEntryPoint()->Reset();
        HeapDelete(loopBodyWorkItem);
    }
    else
    {
        Assert(GetJitMode() == ExecutionMode::FullJit); // simple JIT work items are not removed from the queue

        GetFunctionBody()->OnFullJitDequeued(static_cast<Js::FunctionEntryPointInfo *>(GetEntryPoint()));

        // Add it back to the list of available functions to be jitted
        generator->AddWorkItem(this);
    }
}
예제 #20
0
// This is called at process detach.
// threadcontext created from runtime should not be destroyed in ThreadBoundThreadContext
// we should clean them up at process detach only as runtime can be used in other threads
// even after the current physical thread was destroyed.
// This is called after ThreadBoundThreadContext are cleaned up, so the remaining items
// in the globalthreadContext linklist should be for jsrt only.
void JsrtRuntime::Uninitialize()
{
    ThreadContext* currentThreadContext = ThreadContext::GetThreadContextList();
    ThreadContext* tmpThreadContext;
    while (currentThreadContext)
    {
        Assert(!currentThreadContext->IsScriptActive());
        JsrtRuntime* currentRuntime = static_cast<JsrtRuntime*>(currentThreadContext->GetJSRTRuntime());
        tmpThreadContext = currentThreadContext;
        currentThreadContext = currentThreadContext->Next();

        currentRuntime->CloseContexts();
        RentalThreadContextManager::DestroyThreadContext(tmpThreadContext);
        HeapDelete(currentRuntime);
    }
}
예제 #21
0
    void JavascriptSharedArrayBuffer::Finalize(bool isShutdown)
    {
        if (sharedContents == nullptr)
        {
            return;
        }

        uint ref = sharedContents->Release();
        if (ref == 0)
        {
            this->FreeBuffer(sharedContents->buffer, sharedContents->bufferLength, sharedContents->maxBufferLength);

            Recycler* recycler = GetType()->GetLibrary()->GetRecycler();
            recycler->ReportExternalMemoryFree(sharedContents->bufferLength);

            sharedContents->Cleanup();
            HeapDelete(sharedContents);
        }

        sharedContents = nullptr;
    }
예제 #22
0
파일: s_marea.c 프로젝트: klamonte/maximus
void ParseMsgDivisionEnd(void)
{
  MAINFO mi;
  char *p;

  if (!do_marea)
    return;

  if (! *prefix)
  {
    printf("\n\aError!  MsgDivisionEnd on line %d has no correspondig MsgDivisionBegin!\n", linenum);
    Compiling(-1, NULL, NULL);
    return;
  }

  /* Strip off the trailing dot */

  prefix[strlen(prefix)-1]=0;

  /* Now set the prefix back to the prior area */

  if ((p=strrchr(prefix, '.')) != NULL)
    p[1]=0;
  else *prefix=0;

  MsgAreaWrite(NULL, FALSE);

  memset(&mi, 0, sizeof mi);
  mi.marea=TRUE;

  HeapNew(&mi.h, MAX_MSG_HEAP);

  mi.ma.attribs = MA_DIVEND;
  mi.ma.division = --division;
  HeapAdd(&mi.h, &mi.ma.acs, "");

  MsgAreaWrite(&mi, FALSE);
  HeapDelete(&mi.h);
}
예제 #23
0
bool XDataAllocator::Alloc(ULONG_PTR functionStart, DWORD functionSize,
    ushort pdataCount, ushort xdataSize, SecondaryAllocation* allocation)
{
    XDataAllocation* xdata = static_cast<XDataAllocation*>(allocation);
    Assert(start != nullptr);
    Assert(current != nullptr);
    Assert(current >= start);
    Assert(xdataSize <= XDATA_SIZE);
    Assert(pdataCount == 1);

    // Allocate a new xdata entry
    if((End() - current) >= XDATA_SIZE)
    {
        xdata->address = current;
        current += XDATA_SIZE;
    } // try allocating from the free list
    else if(freeList)
    {
        auto entry = freeList;
        xdata->address = entry->address;
        this->freeList = entry->next;
        HeapDelete(entry);
    }
    else
    {
        xdata->address = nullptr;
        OUTPUT_TRACE(Js::XDataAllocatorPhase, _u("No space for XDATA.\n"));
    }

#ifndef _WIN32
    if (xdata->address)
    {
        ClearHead(xdata->address);  // mark empty .eh_frame
    }
#endif

    return xdata->address != nullptr;
}
예제 #24
0
// This is called at process detach.
// threadcontext created from runtime should not be destroyed in ThreadBoundThreadContext
// we should clean them up at process detach only as runtime can be used in other threads
// even after the current physical thread was destroyed.
// This is called after ThreadBoundThreadContext are cleaned up, so the remaining items
// in the globalthreadContext linklist should be for jsrt only.
void JsrtRuntime::Uninitialize()
{
    ThreadContext* currentThreadContext = ThreadContext::GetThreadContextList();
    ThreadContext* tmpThreadContext;
    while (currentThreadContext)
    {
        Assert(!currentThreadContext->IsScriptActive());
        JsrtRuntime* currentRuntime = static_cast<JsrtRuntime*>(currentThreadContext->GetJSRTRuntime());
        tmpThreadContext = currentThreadContext;
        currentThreadContext = currentThreadContext->Next();

#ifdef CHAKRA_STATIC_LIBRARY
        // xplat-todo: Cleanup staticlib shutdown. This only shuts down threads.
        // Other closing contexts / finalizers having trouble with current
        // runtime/context.
        RentalThreadContextManager::DestroyThreadContext(tmpThreadContext);
#else
        currentRuntime->CloseContexts();
        RentalThreadContextManager::DestroyThreadContext(tmpThreadContext);
        HeapDelete(currentRuntime);
#endif
    }
}
예제 #25
0
    void JavascriptSharedArrayBuffer::Finalize(bool isShutdown)
    {
        if (sharedContents == nullptr)
        {
            return;
        }

        uint ref = InterlockedDecrement(&sharedContents->refCount);
        if (ref == 0)
        {
#if _WIN64
                //AsmJS Virtual Free
                //TOD - see if isBufferCleared need to be added for free too
                if (IsValidVirtualBufferLength(sharedContents->bufferLength) && !sharedContents->isBufferCleared)
                {
                    LPVOID startBuffer = (LPVOID)((uint64)sharedContents->buffer);
                    BOOL fSuccess = VirtualFree((LPVOID)startBuffer, 0, MEM_RELEASE);
                    Assert(fSuccess);
                    sharedContents->isBufferCleared = true;
                }
                else
                {
                    free(sharedContents->buffer);
                }
#else
                free(sharedContents->buffer);
#endif
            Recycler* recycler = GetType()->GetLibrary()->GetRecycler();
            recycler->ReportExternalMemoryFree(sharedContents->bufferLength);

            sharedContents->Cleanup();
            HeapDelete(sharedContents);
        }

        sharedContents = nullptr;
    }
예제 #26
0
파일: s_marea.c 프로젝트: klamonte/maximus
void ParseMsgDivisionBegin(char *name, char *acs, char *displayfile,
                           char *descript)
{
  MAINFO mi;
  char fullname[PATHLEN];

  if (!do_marea)
    return;

  if (strchr(name, '.'))
    BadDivisionName();

  strcpy(fullname, prefix);
  strcat(fullname, name);

  strcat(prefix, name);
  strcat(prefix, ".");

  MsgAreaWrite(NULL, FALSE);

  memset(&mi, 0, sizeof mi);
  mi.marea=TRUE;

  HeapNew(&mi.h, MAX_MSG_HEAP);

  HeapAdd(&mi.h, &mi.ma.name, fullname);
  HeapAdd(&mi.h, &mi.ma.descript, descript);
  HeapAdd(&mi.h, &mi.ma.acs, acs);
  HeapAdd(&mi.h, &mi.ma.path, displayfile);

  mi.ma.attribs = MA_DIVBEGIN;
  mi.ma.division = division++;

  MsgAreaWrite(&mi, FALSE);
  HeapDelete(&mi.h);
}
ThreadContext * ThreadBoundThreadContextManager::EnsureContextForCurrentThread()
{
    AutoCriticalSection lock(ThreadContext::GetCriticalSection());

    ThreadContextTLSEntry * entry = ThreadContextTLSEntry::GetEntryForCurrentThread();

    if (entry == NULL)
    {
        ThreadContextTLSEntry::CreateEntryForCurrentThread();
        entry = ThreadContextTLSEntry::GetEntryForCurrentThread();
        entries.Prepend(entry);
    }

    ThreadContext * threadContext = entry->GetThreadContext();

    // An existing TLS entry may have a null ThreadContext
    // DllCanUnload may have cleaned out all the TLS entry when the module lock count is 0,
    // but the library didn't get unloaded because someone is holding onto ref count via LoadLibrary.
    // Just reinitialize the thread context.
    if (threadContext == nullptr)
    {
        threadContext = HeapNew(ThreadContext);
        threadContext->SetIsThreadBound();
        if (!ThreadContextTLSEntry::TrySetThreadContext(threadContext))
        {
            HeapDelete(threadContext);
            return NULL;
        }
    }

    Assert(threadContext != NULL);

    s_maxNumberActiveThreadContexts = max(s_maxNumberActiveThreadContexts, GetActiveThreadContextCount());

    return threadContext;
}
예제 #28
0
size_t WeightedMatching(RowStarts *rowptr,ColIndices *colind,ValueType *C,
ValueType *C1,ValueType *dist,ValueType *u,ValueType *v,Indices *p,
Indices *m_inv,Indices *m, Indices n,CompareFunction cmpFunc){

	size_t i,j,i1,jend,k,m_inv_prev;
	size_t match_size=0;
	ValueType curr_shortest_path = (ValueType)0;
	ValueType curr_aug_path = GetMaxTypeValue<ValueType>(); 
	ValueType dist1; Indices itrace;
	BitArray_t *col_marker = CreateBitArray(n);
	BitArray_t *heap_marker = CreateBitArray(n);
	C--;m--;C1--;dist--;u--;v--;p--;m_inv--;
	rowptr--;colind--;
#if BINARY_HEAP
	Heap *bin_heap = NewBinaryHeap(cmpFunc,n,GetDistKeyID);  
	ValueType *dist_ptr = NULL;
#endif
	assert(C1 && dist && u && v && p);
	ComputeInitialExtremeMatch<ValueType,Indices>(u,v,C1,C,m,m_inv,colind,rowptr,n,dist);
	match_size=0;
	for(i=1;i<=n;i++){
		if(m_inv[i]){
			match_size++;
			continue;
		}
		/*
		 *Aim is to find a value for jend such that the path
		 *from i-->jend is the shortest
		 */
		i1 = i; p[i1] = 0; jend=0; itrace=i;
		ResetAllBits(col_marker);
		ResetAllBits(heap_marker);
#if BINARY_HEAP
		bin_heap->n = 0;
		dist_base = (unsigned long)&(dist[1]);
#endif
		curr_shortest_path=(ValueType)0;
		curr_aug_path=GetMaxTypeValue<ValueType>();
		while(1){
			for(k=rowptr[i1];k<rowptr[i1+1];k++){
				j = colind[k];
				if(CheckBit(col_marker,j)){
					continue;
				}
				dist1 = curr_shortest_path + C1[k];
				/*Prune any dist1's > curr_aug_path, since
				 *all the costs>0 
				 */
				if(*((long long int *)&dist1) < *((long long int *)&curr_aug_path)){
					if(!m[j]){
						/*we need itrace because, the last i1 which
						 *we explore may not actually give the shortest 
						 *augmenting path.*/
						jend = j; itrace = i1;
						curr_aug_path = dist1;
					}else if(*((long long int *)&dist1) < *((long long int *)&(dist[j]))){ 
						/*Update the dist*/
						dist[j] = dist1; p[m[j]] = i1;
#if SIMPLE_HEAP
						SetBit(heap_marker,j);
#elif BINARY_HEAP
						if(CheckBit(heap_marker,j)){
							DecreaseKey(bin_heap,j);
						}else{
							InsertHeap(bin_heap,&(dist[j]));
							SetBit(heap_marker,j);
						}
#endif
					}
				}
			}
			if(*((long long int *)&curr_aug_path) <= *((long long int *)&curr_shortest_path)){ 
				break;
			}
			/*We now have a heap of matched cols, so pick the min*/
#ifdef SIMPLE_HEAP
			j = SimplePickMin(heap_marker,dist,n);
			if(j){
				curr_shortest_path = dist[j]; 
				UnsetBit(heap_marker,j); 
#elif BINARY_HEAP
			dist_ptr = (ValueType *) HeapDelete(bin_heap);
			if(dist_ptr){
				assert((unsigned long)dist_ptr >= (unsigned long)&dist[1]);
				j = ((((unsigned long)dist_ptr -
					(unsigned long)&dist[1]))/sizeof(double))+1;
				assert(j>=1 && j<=n);
				curr_shortest_path = dist[j]; 
				UnsetBit(heap_marker,j); 
#endif
				SetBit(col_marker,j);
				i1 = m[j];
			}else{
				break;
			}
		}
		if(jend){ /*We found a shortest augmenting path*/
			j=jend;
			node_t itrace_prev;
			//printf("Shortest augmenting Path {");
			while(itrace){
				m_inv_prev = m_inv[itrace];
				m[j] = itrace; m_inv[itrace]=j;
				//printf("(%u,%u)",itrace,j);
				j=m_inv_prev;
				itrace_prev = itrace;
				itrace = p[itrace];
				if(itrace){
				//	printf("(%u,%u)",itrace_prev,m_inv_prev);
				}
			}
			match_size++;
			//printf("}\n");
			/*Update the cost with new match m*/
			for(j=1;j<=n;j++){
				if(CheckBit(col_marker,j)){
					u[j] = (u[j]+dist[j])-curr_aug_path;
					/*Reset the dist values*/
				}
			}
			for(i1=1;i1<=n;i1++){
				if(!m_inv[i1]) continue;
				j = m_inv[i1];
				for(k=rowptr[i1];k<rowptr[i1+1];k++){
					if(colind[k] == j){
						v[i1] = C[k] - u[j];
					}
				}
			}
			/*Update the cost*/
			for(i1=1;i1<=n;i1++){
				for(k=rowptr[i1];k<rowptr[i1+1];k++){
					j = colind[k];
					C1[k] = C[k]-(u[j]+v[i1]);
				}
				/*The index should be j rather than i1 but just 
				 *avoiding another loop*/
				dist[i1] = GetMaxTypeValue<double>();
			}
		}
	}
	FreeBitArray(col_marker);
	FreeBitArray(heap_marker);
#ifdef BINARY_HEAP	
	FreeHeap(bin_heap);
#endif

	return match_size;
}
/*O(n) time picking the maximum from the heap_marker */
node_t SimplePickMin(BitArray_t *bit_heap,double *dist,node_t n){
	node_t min_j=0;node_t j; 
	double curr_min = MAX_DOUBLE_VALUE; 
	for(j=1;j<=n;j++){
		if(CheckBit(bit_heap,j) && dist[j] < curr_min){
			min_j = j;
			curr_min = dist[j];
		}
	}
	return min_j;
}
예제 #29
0
파일: s_marea.c 프로젝트: klamonte/maximus
int ParseMsgArea(FILE *ctlfile, char *name)
{
  char line[PATHLEN];
  char fullname[PATHLEN];
  static MAINFO mi;
  OVRLIST ol;

  struct _vbtab verbs[]=
  {
    {0,           "acs",          &mi.ma.acs},
    {FiltPath,    "path",         &mi.ma.path},
    {0,           "tag",          &mi.ma.echo_tag},
    {0,           "desc",         &mi.ma.descript},
    {0,           "description",  &mi.ma.descript},
    {FiltOrigin,  "origin",       &mi.ma.origin},
#ifdef MAX_TRACKER
    {FiltOwner,   "owner",        NULL},
#endif
    {FiltMenuname,"menuname",     NULL},
    {FiltOverride,"override",     NULL},
    {FiltStyle,   "style",        NULL},
    {FiltRenum,   "renum",        NULL},
    {FiltBarricade,"barricade",   NULL},
    {0,           "app",          NULL},
    {0,           "application",  NULL},
    {0,           "attachpath",   &mi.ma.attachpath},
    {0,           NULL,           NULL}
  };


  if (strchr(name, '.'))
    BadDivisionName();


  if (do_marea)
  {
    /* Make sure that area file is open */

    MsgAreaWrite(NULL, FALSE);

    memset(&mi, 0, sizeof mi);
    mi.marea=TRUE;
    mi.ma.division=division;

    mi.ma.primary=prm.address[0];
    mi.ma.seenby=prm.address[!!prm.address[0].point && prm.address[1].zone];

    HeapNew(&mi.h, MAX_MSG_HEAP);

    strcpy(fullname, prefix);
    strcat(fullname, name);

    HeapAdd(&mi.h, &mi.ma.name, fullname);

#ifdef MAX_TRACKER
    *toNewOwner=0;
#endif
  }

  while (fgets(line, PATHLEN, ctlfile))
    if (VerbParse(&mi, do_marea ? verbs : NULL, line))
      break;

  if (do_marea)
  {
    MsgAreaWrite(&mi, FALSE);

    for (ol=mi.ol; ol; ol=ol->next)
      free(ol);

    HeapDelete(&mi.h);
  }

  return 0;
}
void ThreadBoundThreadContextManager::DestroyAllContexts()
{
#if ENABLE_BACKGROUND_JOB_PROCESSOR
    JsUtil::BackgroundJobProcessor * jobProcessor = NULL;
#endif
    
    {
        AutoCriticalSection lock(ThreadContext::GetCriticalSection());

        ThreadContextTLSEntry * currentEntry = ThreadContextTLSEntry::GetEntryForCurrentThread();

        if (currentEntry == NULL)
        {
            // We need a current thread entry so that we can use it to release any thread contexts
            // we find below.
            try
            {
                AUTO_NESTED_HANDLED_EXCEPTION_TYPE(ExceptionType_OutOfMemory);
                currentEntry = ThreadContextTLSEntry::CreateEntryForCurrentThread();
                entries.Prepend(currentEntry);
            }
            catch (Js::OutOfMemoryException)
            {
                return;
            }
        }
        else
        {
            // We need to clear out the current thread entry so that we can use it to release any
            // thread contexts we find below.
            ThreadContext * threadContext = static_cast<ThreadContext *>(currentEntry->GetThreadContext());

            if (threadContext != NULL)
            {
                if (threadContext->IsThreadBound())
                {
                    ShutdownThreadContext(threadContext);
                    ThreadContextTLSEntry::ClearThreadContext(currentEntry, false);
                }
                else
                {
                    ThreadContextTLSEntry::ClearThreadContext(currentEntry, true);
                }
            }
        }

        EntryList::Iterator iter(&entries);

        while (iter.Next())
        {
            ThreadContextTLSEntry * entry = iter.Data();
            ThreadContext * threadContext =  static_cast<ThreadContext *>(entry->GetThreadContext());

            if (threadContext != nullptr)
            {
                // Found a thread context. Remove it from the containing entry.
                ThreadContextTLSEntry::ClearThreadContext(entry, true);
                // Now set it to our thread's entry.
                ThreadContextTLSEntry::SetThreadContext(currentEntry, threadContext);
                // Clear it out.
                ShutdownThreadContext(threadContext);
                // Now clear it out of our entry.
                ThreadContextTLSEntry::ClearThreadContext(currentEntry, false);
            }
        }

        // We can only clean up our own TLS entry, so we're going to go ahead and do that here.
        entries.Remove(currentEntry);
        ThreadContextTLSEntry::CleanupThread();

#if ENABLE_BACKGROUND_JOB_PROCESSOR
        if (s_sharedJobProcessor != NULL)
        {
            jobProcessor = s_sharedJobProcessor;
            s_sharedJobProcessor = NULL;

            jobProcessor->Close();
        }
#endif
    }

#if ENABLE_BACKGROUND_JOB_PROCESSOR
    if (jobProcessor != NULL)
    {
        HeapDelete(jobProcessor);
    }
#endif
}