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

📄 win32.cxx

📁 pwlib源码库
💻 CXX
📖 第 1 页 / 共 4 页
字号:
  if ((osError & PWIN32ErrorFlag) == 0)    return psprintf("C runtime error %u", osError);  DWORD err = osError & ~PWIN32ErrorFlag;  static const struct {    DWORD id;    const char * msg;  } win32_errlist[] = {    { ERROR_FILE_NOT_FOUND,     "File not found" },    { ERROR_PATH_NOT_FOUND,     "Path not found" },    { ERROR_ACCESS_DENIED,      "Access denied" },    { ERROR_NOT_ENOUGH_MEMORY,  "Not enough memory" },    { ERROR_INVALID_FUNCTION,   "Invalid function" },    { WSAEADDRINUSE,            "Address in use" },    { WSAENETDOWN,              "Network subsystem failed" },    { WSAEISCONN,               "Socket is already connected" },    { WSAENETUNREACH,           "Network unreachable" },    { WSAEHOSTUNREACH,          "Host unreachable" },    { WSAECONNREFUSED,          "Connection refused" },    { WSAEINVAL,                "Invalid operation" },    { WSAENOTCONN,              "Socket not connected" },    { WSAECONNABORTED,          "Connection aborted" },    { WSAECONNRESET,            "Connection reset" },    { WSAESHUTDOWN,             "Connection shutdown" },    { WSAENOTSOCK,              "Socket closed or invalid" },    { WSAETIMEDOUT,             "Timed out" },    { WSAEMSGSIZE,              "Message larger than buffer" },    { WSAEWOULDBLOCK,           "Would block" },    { 0x1000000,                "High level protocol failure" }  };  for (PINDEX i = 0; i < PARRAYSIZE(win32_errlist); i++)    if (win32_errlist[i].id == err)      return win32_errlist[i].msg;  return psprintf("WIN32 error %u", err);}BOOL PChannel::ConvertOSError(int status, Errors & lastError, int & osError){  if (status >= 0) {    lastError = NoError;    osError = 0;    return TRUE;  }  if (status != -2)    osError = errno;  else {    osError = GetLastError();    switch (osError) {      case ERROR_INVALID_HANDLE :      case WSAEBADF :        osError = EBADF;        break;      case ERROR_INVALID_PARAMETER :      case WSAEINVAL :        osError = EINVAL;        break;      case ERROR_ACCESS_DENIED :      case WSAEACCES :        osError = EACCES;        break;      case ERROR_NOT_ENOUGH_MEMORY :        osError = ENOMEM;        break;      case WSAEINTR :        osError = EINTR;        break;      case WSAEMSGSIZE :        osError |= PWIN32ErrorFlag;        lastError = BufferTooSmall;        return FALSE;      case WSAEWOULDBLOCK :      case WSAETIMEDOUT :        osError |= PWIN32ErrorFlag;        lastError = Timeout;        return FALSE;      default :        osError |= PWIN32ErrorFlag;    }  }  switch (osError) {    case 0 :      lastError = NoError;      return TRUE;    case ENOENT :      lastError = NotFound;      break;    case EEXIST :      lastError = FileExists;      break;    case EACCES :      lastError = AccessDenied;      break;    case ENOMEM :      lastError = NoMemory;      break;    case ENOSPC :      lastError = DiskFull;      break;    case EINVAL :      lastError = BadParameter;      break;    case EBADF :      lastError = NotOpen;      break;    case EAGAIN :      lastError = Timeout;      break;    case EINTR :      lastError = Interrupted;      break;    default :      lastError = Miscellaneous;  }  return FALSE;}///////////////////////////////////////////////////////////////////////////////// PWin32OverlappedPWin32Overlapped::PWin32Overlapped(){  memset(this, 0, sizeof(*this));  hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);}PWin32Overlapped::~PWin32Overlapped(){  if (hEvent != NULL)    CloseHandle(hEvent);}void PWin32Overlapped::Reset(){  Offset = OffsetHigh = 0;  if (hEvent != NULL)    ResetEvent(hEvent);}///////////////////////////////////////////////////////////////////////////////// ThreadsUINT __stdcall PThread::MainFunction(void * threadPtr){  PThread * thread = (PThread *)PAssertNULL(threadPtr);  thread->SetThreadName(thread->GetThreadName());  PProcess & process = PProcess::Current();#ifndef _WIN32_WCE  AttachThreadInput(thread->threadId, ((PThread&)process).threadId, TRUE);  AttachThreadInput(((PThread&)process).threadId, thread->threadId, TRUE);#endif  process.activeThreadMutex.Wait();  process.activeThreads.SetAt(thread->threadId, thread);  process.activeThreadMutex.Signal();  process.SignalTimerChange();#if defined(_WIN32_DCOM)  ::CoInitializeEx(NULL, COINIT_MULTITHREADED);#endif  thread->Main();#if defined(_WIN32_DCOM)  ::CoUninitialize();#endif  return 0;}PThread::PThread(PINDEX stackSize,                 AutoDeleteFlag deletion,                 Priority priorityLevel,                 const PString & name)  : threadName(name){  PAssert(stackSize > 0, PInvalidParameter);  originalStackSize = stackSize;  autoDelete = deletion == AutoDeleteThread;#ifndef _WIN32_WCE  threadHandle = (HANDLE)_beginthreadex(NULL, stackSize, MainFunction,                                        this, CREATE_SUSPENDED, &threadId);#else   threadHandle = CreateThread(NULL, stackSize,                                (LPTHREAD_START_ROUTINE)MainFunction,                               this, CREATE_SUSPENDED, (LPDWORD) &threadId);#endif  PAssertOS(threadHandle != NULL);  SetPriority(priorityLevel);  traceBlockIndentLevel = 0;  if (autoDelete) {    PProcess & process = PProcess::Current();    process.deleteThreadMutex.Wait();    process.autoDeleteThreads.Append(this);    process.deleteThreadMutex.Signal();  }}PThread::~PThread(){  if (originalStackSize <= 0)    return;  PProcess & process = PProcess::Current();  process.activeThreadMutex.Wait();  process.activeThreads.SetAt(threadId, NULL);  process.activeThreadMutex.Signal();  if (!IsTerminated())    Terminate();  if (threadHandle != NULL)    CloseHandle(threadHandle);}void PThread::Restart(){  PAssert(IsTerminated(), "Cannot restart running thread");#ifndef _WIN32_WCE  threadHandle = (HANDLE)_beginthreadex(NULL,                         originalStackSize, MainFunction, this, 0, &threadId);#else   threadHandle = CreateThread(NULL, originalStackSize, 								(LPTHREAD_START_ROUTINE) MainFunction,							    this, 0, (LPDWORD) &threadId);#endif  PAssertOS(threadHandle != NULL);}void PThread::Terminate(){  PAssert(originalStackSize > 0, PLogicError);  if (Current() == this)    ExitThread(0);  else    TerminateThread(threadHandle, 1);}BOOL PThread::IsTerminated() const{  if (this == PThread::Current())    return FALSE;  return WaitForTermination(0);}void PThread::WaitForTermination() const{  WaitForTermination(PMaxTimeInterval);}BOOL PThread::WaitForTermination(const PTimeInterval & maxWait) const{  if ((this == PThread::Current()) || threadHandle == NULL) {    PTRACE(2, "WaitForTermination short circuited");    return TRUE;  }  DWORD result;  PINDEX retries = 10;  while ((result = WaitForSingleObject(threadHandle, maxWait.GetInterval())) != WAIT_TIMEOUT) {    if (result == WAIT_OBJECT_0)      return TRUE;    if (::GetLastError() != ERROR_INVALID_HANDLE) {      PAssertAlways(POperatingSystemError);      return TRUE;    }    if (retries == 0)      return TRUE;    retries--;  }  return FALSE;}void PThread::Suspend(BOOL susp){  PAssert(!IsTerminated(), "Operation on terminated thread");  if (susp)    SuspendThread(threadHandle);  else    Resume();}void PThread::Resume(){  PAssert(!IsTerminated(), "Operation on terminated thread");  ResumeThread(threadHandle);}BOOL PThread::IsSuspended() const{  SuspendThread(threadHandle);  return ResumeThread(threadHandle) > 1;}void PThread::SetAutoDelete(AutoDeleteFlag deletion){  PAssert(deletion != AutoDeleteThread || this != &PProcess::Current(), PLogicError);  PProcess & process = PProcess::Current();  if (autoDelete && deletion != AutoDeleteThread) {    process.deleteThreadMutex.Wait();    process.autoDeleteThreads.DisallowDeleteObjects();    process.autoDeleteThreads.Remove(this);    process.autoDeleteThreads.AllowDeleteObjects();    process.deleteThreadMutex.Signal();  }  else if (!autoDelete && deletion == AutoDeleteThread) {    process.deleteThreadMutex.Wait();    process.autoDeleteThreads.Append(this);    process.deleteThreadMutex.Signal();  }  autoDelete = deletion == AutoDeleteThread;}#if !defined(_WIN32_WCE) || (_WIN32_WCE < 300)#define PTHREAD_PRIORITY_LOWEST THREAD_PRIORITY_LOWEST#define PTHREAD_PRIORITY_BELOW_NORMAL THREAD_PRIORITY_BELOW_NORMAL#define PTHREAD_PRIORITY_NORMAL THREAD_PRIORITY_NORMAL#define PTHREAD_PRIORITY_ABOVE_NORMAL THREAD_PRIORITY_ABOVE_NORMAL#define PTHREAD_PRIORITY_HIGHEST THREAD_PRIORITY_HIGHEST#else#define PTHREAD_PRIORITY_LOWEST 243#define PTHREAD_PRIORITY_BELOW_NORMAL 245#define PTHREAD_PRIORITY_NORMAL 247#define PTHREAD_PRIORITY_ABOVE_NORMAL 249#define PTHREAD_PRIORITY_HIGHEST 251#endifvoid PThread::SetPriority(Priority priorityLevel){  PAssert(!IsTerminated(), "Operation on terminated thread");  static int const priorities[NumPriorities] = {    PTHREAD_PRIORITY_LOWEST,    PTHREAD_PRIORITY_BELOW_NORMAL,    PTHREAD_PRIORITY_NORMAL,    PTHREAD_PRIORITY_ABOVE_NORMAL,    PTHREAD_PRIORITY_HIGHEST  };  SetThreadPriority(threadHandle, priorities[priorityLevel]);}PThread::Priority PThread::GetPriority() const{  PAssert(!IsTerminated(), "Operation on terminated thread");  switch (GetThreadPriority(threadHandle)) {    case PTHREAD_PRIORITY_LOWEST :      return LowestPriority;    case PTHREAD_PRIORITY_BELOW_NORMAL :      return LowPriority;    case PTHREAD_PRIORITY_NORMAL :      return NormalPriority;    case PTHREAD_PRIORITY_ABOVE_NORMAL :      return HighPriority;    case PTHREAD_PRIORITY_HIGHEST :      return HighestPriority;  }  PAssertAlways(POperatingSystemError);  return LowestPriority;}void PThread::Yield(){  ::Sleep(0);}void PThread::InitialiseProcessThread(){  originalStackSize = 0;  autoDelete = FALSE;  threadHandle = GetCurrentThread();  threadId = GetCurrentThreadId();  ((PProcess *)this)->activeThreads.DisallowDeleteObjects();  ((PProcess *)this)->activeThreads.SetAt(threadId, this);  traceBlockIndentLevel = 0;}PThread * PThread::Current(){  PProcess & process = PProcess::Current();  process.activeThreadMutex.Wait();  PThread * thread = process.activeThreads.GetAt(GetCurrentThreadId());  process.activeThreadMutex.Signal();  return thread;}///////////////////////////////////////////////////////////////////////////////// PProcess::TimerThreadPProcess::HouseKeepingThread::HouseKeepingThread()  : PThread(1000, NoAutoDeleteThread, NormalPriority, "PWLib Housekeeper"){  Resume();}void PProcess::HouseKeepingThread::Main(){  PProcess & process = PProcess::Current();  for (;;) {    // collect a list of thread handles to check, and clean up     // handles for threads that disappeared without telling us    process.deleteThreadMutex.Wait();    HANDLE handles[MAXIMUM_WAIT_OBJECTS];    DWORD numHandles = 1;    DWORD dwFlags;    handles[0] = breakBlock.GetHandle();    for (PINDEX i = 0; i < process.autoDeleteThreads.GetSize(); i++) {      PThread & thread = process.autoDeleteThreads[i];      if (thread.IsTerminated())        process.autoDeleteThreads.RemoveAt(i--);      else {        handles[numHandles] = thread.GetHandle();        // make sure we don't put invalid handles into the list#ifndef _WIN32_WCE        if (GetHandleInformation(handles[numHandles], &dwFlags) == 0) {          PTRACE(2, "Refused to put invalid handle into wait list");        }        else#endif        // don't put the handle for the current process in the list		if (handles[numHandles] != process.GetHandle()) {          numHandles++;          if (numHandles >= MAXIMUM_WAIT_OBJECTS)            break;        }      }    }    process.deleteThreadMutex.Signal();    PTimeInterval nextTimer = process.timers.Process();    DWORD delay;    if (nextTimer == PMaxTimeInterval)      delay = INFINITE;    else if (nextTimer > 1000)      delay = 1000;    else      delay = nextTimer.GetInterval();    DWORD result;    int retries = 100;    while ((result = WaitForMultipleObjects(numHandles, handles, FALSE, delay)) == WAIT_FAILED) {      // if we get an invalid handle error, than assume this is because a thread ended between      // creating the handle list and testing it. So, cleanup the list before calling       // WaitForMultipleObjects again      if (::GetLastError() == ERROR_INVALID_HANDLE)        break;      // sometimes WaitForMultipleObjects fails. No idea why, so allow some retries      else {        retries--;        if (retries <= 0)          break;      }    }  }}

⌨️ 快捷键说明

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