Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

337 lines
8.4 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: devlock.hxx
  3. *
  4. * Device locking object.
  5. *
  6. * Created: 03-Jul-1990 17:41:42
  7. * Author: Donald Sidoroff [donalds]
  8. *
  9. * Copyright (c) 1992-1999 Microsoft Corporation
  10. \**************************************************************************/
  11. #define DLO_VALID 0x00000001
  12. #define DLO_ALLOC 0x00000010 // for MULTIDEVLOCKOBJ
  13. #define DLO_LOCKED 0x00000020 // for MULTIDEVLOCKOBJ
  14. #define DLO_SHAREDACCESS 0x00000100
  15. class DEVLOCKOBJ
  16. {
  17. private:
  18. HSEMAPHORE hsemTrg;
  19. PPDEV ppdevTrg;
  20. FLONG fl;
  21. public:
  22. BOOL bLock(XDCOBJ&);
  23. VOID vLockNoDrawing(XDCOBJ&);
  24. VOID vLock(PDEVOBJ& po)
  25. {
  26. GDIFunctionID(DEVLOCKOBJ::vLock);
  27. hsemTrg = NULL;
  28. fl = DLO_VALID;
  29. if (po.bDisplayPDEV())
  30. {
  31. //
  32. // make sure we don't have any wrong sequence of acquiring locks
  33. // should always acquire a DEVLOCK before we have the palette semaphore
  34. //
  35. ASSERTGDI (!GreIsSemaphoreOwnedByCurrentThread(ghsemPalette) ||
  36. GreIsSemaphoreOwnedByCurrentThread(po.hsemDevLock()),
  37. "potential deadlock!\n");
  38. hsemTrg = po.hsemDevLock();
  39. ppdevTrg = po.ppdev;
  40. GreAcquireSemaphoreEx(hsemTrg, SEMORDER_DEVLOCK, NULL);
  41. GreEnterMonitoredSection(ppdevTrg, WD_DEVLOCK);
  42. }
  43. }
  44. DEVLOCKOBJ() { }
  45. DEVLOCKOBJ(XDCOBJ& dco) { bLock(dco); }
  46. DEVLOCKOBJ(PDEVOBJ& po) { vLock(po); }
  47. // vDestructor -- manual version of the normal C++ destructor; needed
  48. // by the C-callable OpenGL interface.
  49. VOID vDestructor()
  50. {
  51. GDIFunctionID(DEVLOCKOBJ::vDestructor);
  52. if(fl & DLO_SHAREDACCESS)
  53. {
  54. GreReleaseSemaphore(ghsemShareDevLock);
  55. }
  56. else if (hsemTrg != NULL)
  57. {
  58. GreExitMonitoredSection(ppdevTrg, WD_DEVLOCK);
  59. GreReleaseSemaphoreEx(hsemTrg);
  60. }
  61. #ifdef CHECK_SEMAPHORE_USAGE
  62. GreCheckSemaphoreUsage();
  63. #endif
  64. }
  65. VOID vDestructorNULL()
  66. {
  67. GDIFunctionID(DEVLOCKOBJ::vDestructorNULL);
  68. if(fl & DLO_SHAREDACCESS)
  69. {
  70. GreReleaseSemaphore(ghsemShareDevLock);
  71. fl &= ~(DLO_SHAREDACCESS);
  72. }
  73. else if (hsemTrg != NULL)
  74. {
  75. ASSERT(ppdevTrg);
  76. GreExitMonitoredSection(ppdevTrg, WD_DEVLOCK);
  77. GreReleaseSemaphoreEx(hsemTrg);
  78. hsemTrg = NULL;
  79. ppdevTrg = NULL;
  80. }
  81. #ifdef CHECK_SEMAPHORE_USAGE
  82. GreCheckSemaphoreUsage();
  83. #endif
  84. }
  85. ~DEVLOCKOBJ() { vDestructor(); }
  86. HSEMAPHORE hsemDst() { return(hsemTrg); }
  87. BOOL bValid() { return(fl & DLO_VALID); }
  88. VOID vInit()
  89. {
  90. hsemTrg = NULL;
  91. ppdevTrg = NULL;
  92. fl = 0;
  93. }
  94. };
  95. /*********************************Class************************************\
  96. * class DEVLOCKBLTOBJ
  97. *
  98. * Lock the target and optionally the source for BitBlt, et. al.
  99. *
  100. * History:
  101. * Mon 18-Apr-1994 -by- Patrick Haluptzok [patrickh]
  102. * Support Async devices.
  103. *
  104. * 17-Nov-1992 -by- Donald Sidoroff [donalds]
  105. * Wrote it.
  106. \**************************************************************************/
  107. class DEVLOCKBLTOBJ
  108. {
  109. private:
  110. HSEMAPHORE hsemTrg;
  111. HSEMAPHORE hsemSrc;
  112. PPDEV ppdevTrg;
  113. PPDEV ppdevSrc;
  114. FLONG fl;
  115. public:
  116. BOOL bLock(XDCOBJ&);
  117. BOOL bLock(XDCOBJ&,XDCOBJ&);
  118. DEVLOCKBLTOBJ(XDCOBJ& dco) { bLock(dco); }
  119. DEVLOCKBLTOBJ(XDCOBJ& dcoTrg,XDCOBJ& dcoSrc) { bLock(dcoTrg,dcoSrc); }
  120. DEVLOCKBLTOBJ() {}
  121. //
  122. // vUnLock and vLock are used to temparily
  123. // release and re-aquire the DEVLOCK
  124. //
  125. VOID vUnLock ()
  126. {
  127. GDIFunctionID(DEVLOCKBLTOBJ::vUnLock);
  128. if (hsemTrg != NULL)
  129. {
  130. ASSERT(ppdevTrg);
  131. GreExitMonitoredSection(ppdevTrg, WD_DEVLOCK);
  132. GreReleaseSemaphore(hsemTrg);
  133. hsemTrg = NULL;
  134. ppdevTrg = NULL;
  135. }
  136. if (hsemSrc != NULL)
  137. {
  138. ASSERT(ppdevSrc);
  139. GreExitMonitoredSection(ppdevSrc, WD_DEVLOCK);
  140. GreReleaseSemaphore(hsemSrc);
  141. hsemSrc = NULL;
  142. ppdevSrc = NULL;
  143. }
  144. if(fl & DLO_SHAREDACCESS)
  145. {
  146. GreReleaseSemaphore(ghsemShareDevLock);
  147. fl &= ~(DLO_SHAREDACCESS);
  148. }
  149. #ifdef CHECK_SEMAPHORE_USAGE
  150. GreCheckSemaphoreUsage();
  151. #endif
  152. }
  153. ~DEVLOCKBLTOBJ()
  154. {
  155. GDIFunctionID(DEVLOCKBLTOBJ::~DEVLOCKBLTOBJ);
  156. if (hsemTrg != NULL)
  157. {
  158. ASSERT(ppdevTrg);
  159. GreExitMonitoredSection(ppdevTrg, WD_DEVLOCK);
  160. GreReleaseSemaphore(hsemTrg);
  161. }
  162. if (hsemSrc != NULL)
  163. {
  164. ASSERT(ppdevSrc);
  165. GreExitMonitoredSection(ppdevSrc, WD_DEVLOCK);
  166. GreReleaseSemaphore(hsemSrc);
  167. }
  168. if(fl & DLO_SHAREDACCESS)
  169. {
  170. GreReleaseSemaphore(ghsemShareDevLock);
  171. }
  172. #ifdef CHECK_SEMAPHORE_USAGE
  173. GreCheckSemaphoreUsage();
  174. #endif
  175. }
  176. BOOL bValid() { return(fl & DLO_VALID); }
  177. VOID vInit()
  178. {
  179. hsemTrg = NULL;
  180. hsemSrc = NULL;
  181. ppdevTrg = NULL;
  182. ppdevSrc = NULL;
  183. fl = 0;
  184. }
  185. };
  186. /*********************************Class************************************\
  187. * class MULTIDEVLOCLOBJ
  188. *
  189. * Lock the all PDEV for the MDEV.
  190. *
  191. * History:
  192. * Tue 07-Jul-1998 -by- Hideyuki Nagase [hideyukn]
  193. * Wrote it.
  194. \**************************************************************************/
  195. #define QUICK_MULTIDEVLOCK_SIZE 5
  196. class MULTIDEVLOCKOBJ
  197. {
  198. private:
  199. FLONG fl;
  200. ULONG ulArraySize;
  201. HSEMAPHORE *phsemArray;
  202. HSEMAPHORE hsemQuickBuf[QUICK_MULTIDEVLOCK_SIZE];
  203. public:
  204. MULTIDEVLOCKOBJ() { vInit(NULL); }
  205. MULTIDEVLOCKOBJ(PMDEV pmdev) { vInit(pmdev); }
  206. ~MULTIDEVLOCKOBJ()
  207. {
  208. vUnlock();
  209. if (fl & DLO_ALLOC)
  210. {
  211. VFREEMEM(phsemArray);
  212. }
  213. }
  214. BOOL bValid() { return(fl & DLO_VALID); }
  215. BOOL bLocked() { return(fl & DLO_LOCKED); }
  216. BOOL bValidLockTable() { return(phsemArray != NULL); }
  217. VOID vInit(PMDEV pmdev)
  218. {
  219. fl = 0;
  220. ulArraySize = 0;
  221. phsemArray = NULL;
  222. if (pmdev)
  223. {
  224. // + 1 : for parent pdev's lock
  225. ulArraySize = pmdev->chdev;
  226. if (ulArraySize > QUICK_MULTIDEVLOCK_SIZE)
  227. {
  228. phsemArray = (HSEMAPHORE *) PALLOCNOZ(sizeof(HSEMAPHORE) * pmdev->chdev,'pmtG');
  229. if (phsemArray)
  230. {
  231. fl = (DLO_VALID|DLO_ALLOC);
  232. }
  233. }
  234. else
  235. {
  236. phsemArray = hsemQuickBuf;
  237. fl = DLO_VALID;
  238. }
  239. if (phsemArray)
  240. {
  241. PDEVOBJ po;
  242. // Save all the children's devlock to buffer in class
  243. for (ULONG i = 0; i < pmdev->chdev; i++)
  244. {
  245. po.vInit(pmdev->Dev[i].hdev);
  246. *(phsemArray + i) = po.hsemDevLock();
  247. }
  248. }
  249. }
  250. else
  251. {
  252. fl = DLO_VALID;
  253. }
  254. }
  255. VOID vLock()
  256. {
  257. GDIFunctionID(MULTIDEVLOCKOBJ::vLock);
  258. if (bValidLockTable() && !bLocked())
  259. {
  260. for (ULONG i = 0; i < ulArraySize; i++)
  261. {
  262. GreAcquireSemaphoreEx(*(phsemArray+i), SEMORDER_DEVLOCK, NULL);
  263. }
  264. fl |= DLO_LOCKED;
  265. }
  266. }
  267. VOID vUnlock()
  268. {
  269. GDIFunctionID(MULTIDEVLOCKOBJ::vUnLock);
  270. if (bValidLockTable() && bLocked())
  271. {
  272. for (ULONG i = 0; i < ulArraySize; i++)
  273. {
  274. GreReleaseSemaphoreEx(*(phsemArray+i));
  275. }
  276. fl &= ~DLO_LOCKED;
  277. }
  278. }
  279. };