⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tlibvx.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/*
 * tlibvx.cxx
 *
 * Thread library implementation for VxWorks
 *
 * Portable Windows Library
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is Portable Windows Library.
 *
 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
 *
 * Portions are Copyright (c) 1993-1998 Equivalence Pty. Ltd.
 *
 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
 * All Rights Reserved.
 *
 * Contributor(s):  ______________________________________.
 *
 * $Log: tlibvx.cxx,v $
 * Revision 1.1  2006/06/29 04:18:41  joegenbaclor
 * *** empty log message ***
 *
 * Revision 1.4  2004/07/11 07:56:36  csoutheren
 * Applied jumbo VxWorks patch, thanks to Eize Slange
 *
 * 
 * Revision 1.3  2003/05/21 00:49:16  csoutheren
 *  Added PreShutdown to ~PProcess
 * 
 * Revision 1.2  2003/02/26 01:14:27  robertj
 *  Fixed race condition where thread can terminatebefore an IsSuspeded() call
 *  occurs and cause an assert, thanks Sebastian Meyer
 * 
 * Revision 1.1  2002/11/05 01:43:39  robertj
 *  Added missing VxWorks files. Thanks Andreas Sikkema
 *
 * Revision 1.0 ?????????????
*/


class PProcess;
class PSemaphore;

#include <ptlib.h>
#include <ptlib/socket.h>
#include <trclib.h>
#include <usrlib.h>
// Forward to undocumented system call
extern "C" void dbgPrintCall(INSTR * callAdrs, int funcAdrs, int nargs,
                             UINT32 * pArgs);

#define VX_LOWEST_PRIORITY          250
#define VX_LOW_PRIORITY             200
#define VX_NORMAL_PRIORITY          150
#define VX_DISPLAY_PRIORITY         100
#define VX_URGENT_DISPLAY_PRIORITY  50  

///////////////////////////////////////////////////////////////////////////////
// Critical Section Implementation
// -------------------------------
class CCriticalSection {
public:
  CCriticalSection();
  ~CCriticalSection();

  void Lock();
  void Unlock();

private:
  int    intLevel;
  STATUS taskLocked;
  bool   locked;
};

CCriticalSection::CCriticalSection()
{
  intLevel   = 0;
  taskLocked = ERROR;
  locked     = false;
}

CCriticalSection::~CCriticalSection()
{
  // Unlock anyway when someone forgot to call Unlock after Lock
  if (locked == true)
    Unlock();
}

void CCriticalSection::Lock()
{
  if (locked == false) {
    if (::intContext() == FALSE)
      taskLocked = ::taskLock();
    else
      taskLocked = ERROR;
    intLevel = ::intLock();
    locked = true;
  }
}

void CCriticalSection::Unlock()
{
  if (locked == true) {
    ::intUnlock(intLevel);
    if (taskLocked == OK) 
      ::taskUnlock();
    locked = false;
  }
}

///////////////////////////////////////////////////////////////////////////////
// Threads
static int const priorities[] = {
  VX_LOWEST_PRIORITY,
  VX_LOW_PRIORITY,
  VX_NORMAL_PRIORITY,
  VX_DISPLAY_PRIORITY,
  VX_URGENT_DISPLAY_PRIORITY
};

int PThread::ThreadFunction(void *threadPtr)
{
	PAssertNULL(threadPtr);
  PThread * thread = (PThread *)threadPtr;
  PProcess & process = PProcess::Current();
  process.activeThreadMutex.Wait();
  process.activeThreads.SetAt(thread->PX_threadId, thread);
  process.activeThreadMutex.Signal();
  process.SignalTimerChange();

  if (::semTake(thread->syncPoint, WAIT_FOREVER) == OK) {
    if (::semDelete(thread->syncPoint) == OK)
      thread->syncPoint = NULL;
  thread->Main();
  }
  else
    printf("::ThreadFunction> ::semTake failed, errno=0x%X\n",errno);
  
  // And delete from administration
  process.activeThreadMutex.Wait();
  process.activeThreads.SetAt(thread->PX_threadId, NULL);
  process.activeThreadMutex.Signal();
  thread->PX_threadId = 0;

  return 0;
}

void PThread::Trace(PThreadIdentifer threadId)
{
  if (threadId == 0)
    threadId = PThread::GetCurrentThreadId();

  printf("Task name=%s\n", ::taskName(threadId));

  ::taskRegsShow(threadId); 
  REG_SET regSet;       
  if (::taskRegsGet(threadId, &regSet) != ERROR)
    ::trcStack(&regSet, (FUNCPTR)dbgPrintCall, threadId);
  else
    printf("::Terminate> ::taskRegsGet failed, errno=0x%X\n", errno);
  ::taskShow(0, 2);
  printf("\n");
  ::checkStack(0);
}

PThread::PThread()
 : PX_threadId(ERROR),
   priority(VX_NORMAL_PRIORITY),
   originalStackSize(0)
{
}

PThread::PThread(PINDEX stackSize,
                 AutoDeleteFlag deletion,
                 Priority priorityLevel,
     		   const PString & name
)
{
  PAssert(stackSize > 0, PInvalidParameter);
  autoDelete = (deletion == AutoDeleteThread);
  originalStackSize = stackSize;

  priority = priorities[priorityLevel];

  syncPoint = ::semMCreate(SEM_Q_FIFO);
  if (syncPoint != NULL) {
    if (::semTake(syncPoint, NO_WAIT) == OK) {
      STATUS taskLocked;
      taskLocked = ::taskLock();
      PX_threadId = ::taskSpawn(name,                         // Name
					priority,                     // Priority 
					0,                            // options	
					stackSize,                    // stacksize
					(FUNCPTR)ThreadFunction,      // entrypoint
					(int)this,0,0,0,0,0,0,0,0,0); // arg 1 --- arg 10

      if (PX_threadId != ERROR) {
        // threads are created suspended
        Suspend();
        ::semGive(syncPoint);

        if (taskLocked == OK) 
          ::taskUnlock();

        if (autoDelete) {
          PProcess & process = PProcess::Current();
          process.deleteThreadMutex.Wait();
          process.autoDeleteThreads.Append(this);
          process.deleteThreadMutex.Signal();
        }
      }
      else {
        if (taskLocked == OK) 
          ::taskUnlock();
        printf("::PThread> ::taskSpawn failed, errno=0x%X\n", errno);
        PX_threadId = 0;
        ::semDelete(syncPoint);
        syncPoint = NULL;
      }                 
    }
    else {
      printf("::PThread> ::semTake failed, errno=0x%X\n", errno);
      ::semDelete(syncPoint);
      syncPoint = NULL;
    }
  }
}


PThread::~PThread()
{
  if (originalStackSize <= 0)
    return;

  if (!IsTerminated())
    Terminate();
}


void PThread::Restart()
{
  if (IsTerminated()) {
    PX_threadId = ::taskSpawn(NULL,                         // Auto name tn
					priority, 										// Priority 
					0,														// options	
					originalStackSize,            // stacksize
					(FUNCPTR)ThreadFunction,			// entrypoint
					(int)this,0,0,0,0,0,0,0,0,0);	// arg 1 --- arg 10
         
    if (PX_threadId == ERROR) {
      printf("::Restart> ::taskSpawn failed, errno=0x%X\n", errno);
      PX_threadId = 0;
    }                  
  }
  else
    printf("::Restart> Cannot restart running thread\n");
}

void PThread::Terminate()
{
  if (originalStackSize <= 0)
    return;
	
  if (!IsTerminated()) {
    if (::taskDelete(PX_threadId) == ERROR)
      printf("::Terminate> ::taskDelete failed, errno=0x%X\n", errno);
    
    // And delete from administration
    PProcess & process = PProcess::Current();
    process.activeThreadMutex.Wait();
    process.activeThreads.SetAt(PX_threadId, NULL);
    process.activeThreadMutex.Signal();
    PX_threadId = 0;
  }
}


BOOL PThread::IsTerminated() const
{
  STATUS stat = ERROR;
  if (PX_threadId != 0)
    stat = ::taskIdVerify(PX_threadId);

		return stat == ERROR;
}


void PThread::WaitForTermination() const
{
  while (!IsTerminated()) {
    Current()->Sleep(100);
	}
}


BOOL PThread::WaitForTermination(const PTimeInterval & maxWait) const
{
  if (PX_threadId == 0)
    return TRUE;

  PTimer timeout = maxWait;
  while (!IsTerminated()) {
    if (timeout == 0)
      return FALSE;
    Current()->Sleep(100);
  }
 return TRUE;
}


void PThread::Suspend(BOOL susp)
{
  if (!IsTerminated()) {
    if (susp) {
      if (::taskSuspend(PX_threadId) == ERROR)
        printf("::Suspend> Thread doesn't want to suspend, errno=0x%X\n", errno);
  }
  else {
      if (::taskResume(PX_threadId) == ERROR)
        printf("::Suspend> Thread doesn't want to resume, errno=0x%X\n", errno);
    }
	}
  else
    printf("::Suspend> Operation on terminated thread\n");
}


void PThread::Resume()
{
	if (!IsTerminated()) {
    if (::taskResume(PX_threadId) == ERROR)
      printf("::Resume> Thread doesn't want to resume, errno=0x%X\n", errno);
	}
  else
    printf("::Resume> Operation on terminated thread\n");
}


BOOL PThread::IsSuspended() const
{
  BOOL isSuspended = FALSE;
  if (!IsTerminated())
    isSuspended = ::taskIsSuspended(PX_threadId);
  else
    printf("::IsSuspended> Operation on terminated thread\n");

  return isSuspended;
}

void PThread::SetAutoDelete(AutoDeleteFlag deletion)
{
  PAssert(deletion != AutoDeleteThread || this != &PProcess::Current(), PLogicError);
  autoDelete = deletion == AutoDeleteThread;
}

void PThread::SetPriority(Priority priorityLevel)
{
  if (!IsTerminated()) {
  priority = priorities[priorityLevel];
      if (::taskPrioritySet(PX_threadId, priority ) == ERROR)
        printf("::SetPriority> ::taskPrioritySet failed, errno: 0x%X\n", errno);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -