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

📄 sync.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
字号:
/* sync.cc: Synchronization functions for cygwin.   This file implements the methods for controlling the "muto" class   which is intended to operate similarly to a mutex but attempts to   avoid making expensive calls to the kernel.   Copyright 2000, 2001, 2002 Red Hat, Inc.   Written by Christopher Faylor <cgf@cygnus.com>This file is part of Cygwin.This software is a copyrighted work licensed under the terms of theCygwin license.  Please consult the file "CYGWIN_LICENSE" fordetails. */#include "winsup.h"#include <stdlib.h>#include <time.h>#include <sys/wait.h>#include <errno.h>#include <stdlib.h>#include "sync.h"#include "security.h"muto NO_COPY muto_start;#undef WaitForSingleObject/* Constructor */muto *muto::init (const char *s){  waiters = -1;  /* Create event which is used in the fallback case when blocking is necessary */  if (!(bruteforce = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL)))    {      DWORD oerr = GetLastError ();      SetLastError (oerr);      return NULL;    }  name = s;  next = muto_start.next;  muto_start.next = this;  return this;}#if 0 /* FIXME: Do we need this? mutos aren't destroyed until process exit *//* Destructor (racy?) */muto::~muto (){  while (visits)    release ();  HANDLE h = bruteforce;  bruteforce = NULL;  /* Just need to close the event handle */  if (h)    CloseHandle (h);}#endif/* Acquire the lock.  Argument is the number of milliseconds to wait for   the lock.  Multiple visits from the same thread are allowed and should   be handled correctly.   Note: The goal here is to minimize, as much as possible, calls to the   OS.  Hence the use of InterlockedIncrement, etc., rather than (much) more   expensive OS mutexes.  */intmuto::acquire (DWORD ms){  DWORD this_tid = GetCurrentThreadId ();  if (tid != this_tid)    {      /* Increment the waiters part of the class.  Need to do this first to	 avoid potential races. */      LONG was_waiting = InterlockedIncrement (&waiters);      /* This is deceptively simple.  Basically, it allows multiple attempts to	 lock the same muto to succeed without attempting to manipulate sync.	 If the muto is already locked then this thread will wait for ms until	 it is signalled by muto::release.  Then it will attempt to grab the	 sync field.  If it succeeds, then this thread owns the muto.	 There is a pathological condition where a thread times out waiting for	 bruteforce but the release code triggers the bruteforce event.  In this	 case, it is possible for a thread which is going to wait for bruteforce	 to wake up immediately.  It will then attempt to grab sync but will fail	 and go back to waiting.  */      if (tid != this_tid && (was_waiting || InterlockedExchange (&sync, 1) != 0))	{	  switch (WaitForSingleObject (bruteforce, ms))	      {	      case WAIT_OBJECT_0:		goto gotit;		break;	      default:		InterlockedDecrement (&waiters);		return 0;	/* failed. */	      }	}    }gotit:  tid = this_tid;	/* register this thread. */  return ++visits;	/* Increment visit count. */}/* Return the muto lock.  Needs to be called once per every acquire. */intmuto::release (){  DWORD this_tid = GetCurrentThreadId ();  if (tid != this_tid || !visits)    {      SetLastError (ERROR_NOT_OWNER);	/* Didn't have the lock. */      return 0;	/* failed. */    }  /* FIXME: Need to check that other thread has not exited, too. */  if (!--visits)    {      tid = 0;		/* We were the last unlocker. */      (void) InterlockedExchange (&sync, 0); /* Reset trigger. */      /* This thread had incremented waiters but had never decremented it.	 Decrement it now.  If it is >= 0 then there are possibly other	 threads waiting for the lock, so trigger bruteforce. */      if (InterlockedDecrement (&waiters) >= 0)	(void) SetEvent (bruteforce); /* Wake up one of the waiting threads */    }  return 1;	/* success. */}/* Call only when we're exiting.  This is not thread safe. */voidmuto::reset (){  visits = sync = tid = 0;  InterlockedExchange (&waiters, -1);  if (bruteforce)    {      CloseHandle (bruteforce);      bruteforce = CreateEvent (&sec_none_nih, FALSE, FALSE, name);    }}

⌨️ 快捷键说明

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