Source code of Windows XP (NT5)
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.

326 lines
8.5 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: ETASK.CXX (16 bit target)
  7. //
  8. // Contents: ETask management code, taken from 16-bit COMPOBJ.CPP
  9. //
  10. // Functions:
  11. //
  12. // History: 08-Mar-94 BobDay Copied parts from \\ole\slm\...\compobj.cpp
  13. // 01-Feb-95 JohannP modified/simplified
  14. //
  15. //--------------------------------------------------------------------------
  16. #include <headers.cxx>
  17. #pragma hdrstop
  18. #include <ole2sp.h>
  19. #include <olecoll.h>
  20. #include <map_kv.h>
  21. #include "comlocal.hxx"
  22. #include "map_htsk.h"
  23. #include "etask.hxx"
  24. #include "call32.hxx"
  25. #include "apilist.hxx"
  26. // NOTE: NEAR forces this variable to be in the default data segment; without
  27. // NEAR, the ambient model of the class CMapHandleEtask, which is FAR,
  28. // causes the variable to be in a far_data segment.
  29. //
  30. // For WIN32/NT this table is in instance data, the table contains exactly one
  31. // entry
  32. //
  33. HTASK v_hTaskCache = NULL;
  34. Etask NEAR v_etaskCache;
  35. // quick check that the etask is valid (e.g., pointers are valid)
  36. INTERNAL_(BOOL) IsValidEtask(HTASK hTask, Etask FAR& etask)
  37. {
  38. Win(Assert(GetCurrentProcess() == hTask));
  39. thkDebugOut((DEB_DLLS16, "IsValidEtask (%X) pMalloc(%p)\n", hTask, etask.m_pMalloc));
  40. #ifdef _CHICAGO_
  41. if ( etask.m_pMalloc != NULL
  42. && !IsValidInterface(etask.m_pMalloc))
  43. #else
  44. if (!IsValidInterface(etask.m_pMalloc))
  45. #endif
  46. {
  47. thkDebugOut((DEB_DLLS16, "IsValidEtask (%X) FALSE\n", hTask));
  48. return FALSE;
  49. }
  50. // FUTURE: verify that stack segment is the same
  51. // FUTURE: verify that hInst/hMod are the same
  52. thkDebugOut((DEB_DLLS16, "IsValidEtask (%X) TRUE\n", hTask));
  53. return TRUE;
  54. }
  55. // if task map empty, clear globals in case lib doesn't get unloaded
  56. INTERNAL_(void) CheckIfMapEmpty(void)
  57. {
  58. // if no more entries, clear v_pMallocShared; this ensures we clear the
  59. // variable if the app holds onto this pointer erroneously.
  60. if (v_mapToEtask.IsEmpty()) {
  61. v_pMallocShared = NULL;
  62. }
  63. }
  64. //+---------------------------------------------------------------------------
  65. //
  66. // Method: LookupEtask
  67. //
  68. // Synopsis: get etask for current task (and also return hTask);
  69. // does not create if none
  70. //
  71. // Arguments: [hTask] --
  72. // [etask] --
  73. //
  74. // Returns:
  75. //
  76. // History: Ole16 created for CompObj 16 bit for Ole2
  77. // 2-03-95 JohannP (Johann Posch) modified/simplified
  78. //
  79. // Notes:
  80. //
  81. //----------------------------------------------------------------------------
  82. STDAPI_(BOOL) LookupEtask(HTASK FAR& hTask, Etask FAR& etask)
  83. {
  84. hTask = GetCurrentProcess();
  85. thkDebugOut((DEB_DLLS16, "LookupEtask on Process (%X) \n", hTask));
  86. if (hTask == v_hTaskCache)
  87. {
  88. thkDebugOut((DEB_DLLS16, "LookupEtask found in cache (%X) \n", hTask));
  89. etask = v_etaskCache;
  90. goto CheckEtask;
  91. }
  92. if (!v_mapToEtask.Lookup(hTask, etask))
  93. {
  94. thkDebugOut((DEB_DLLS16, "LookupEtask faild on lookup (%X) \n", hTask));
  95. return FALSE;
  96. }
  97. else
  98. {
  99. thkDebugOut((DEB_DLLS16, "LookupEtask found in lookup (%X) \n", hTask));
  100. }
  101. // found etask; make this the current cache
  102. v_hTaskCache = hTask;
  103. v_etaskCache = etask;
  104. CheckEtask:
  105. if (IsValidEtask(hTask, etask))
  106. {
  107. return TRUE;
  108. }
  109. else
  110. {
  111. // task got reused; kill cache and entry in map
  112. v_hTaskCache = NULL;
  113. v_mapToEtask.RemoveKey(hTask);
  114. CheckIfMapEmpty();
  115. thkAssert(0 && "LookupEtask - failed (invalid Etask)");
  116. return FALSE;
  117. }
  118. }
  119. //+---------------------------------------------------------------------------
  120. //
  121. // Method: SetEtask
  122. //
  123. // Synopsis: set etask for task given (must be current task); return FALSE
  124. // if OOM (only first time; all other times should return TRUE).
  125. //
  126. // Arguments: [hTask] --
  127. // [etask] --
  128. //
  129. // Returns:
  130. //
  131. // History: Ole16 created for CompObj 16 bit for Ole2
  132. // 02-03-95 JohannP (Johann Posch) modified/simplified
  133. //
  134. // Notes:
  135. //
  136. //----------------------------------------------------------------------------
  137. STDAPI_(BOOL) SetEtask(HTASK hTask, Etask FAR& etask)
  138. {
  139. Win(Assert(GetCurrentProcess() == hTask));
  140. if (!v_mapToEtask.SetAt(hTask, etask))
  141. return FALSE;
  142. Assert(IsValidEtask(hTask, etask));
  143. // map set; make this the current cache
  144. v_hTaskCache = hTask;
  145. v_etaskCache = etask;
  146. return TRUE;
  147. }
  148. //+---------------------------------------------------------------------------
  149. //
  150. // Method: ReleaseEtask
  151. //
  152. // Synopsis: release all fields in the etask; do all the task memory
  153. // (except the task allocator) first; then all the shared
  154. // memory (except the shared allocator); then the shared
  155. // allocator and finally the task allocator.
  156. // Also removes key if htask is given.
  157. //
  158. // Arguments: [htask] --
  159. // [etask] --
  160. //
  161. // Returns:
  162. //
  163. // History: Ole16 created for CompObj 16 bit for Ole2
  164. // 2-03-95 JohannP (Johann Posch) modified/simplified
  165. //
  166. // Notes: Called by daytona and chicago.
  167. //
  168. //----------------------------------------------------------------------------
  169. void ReleaseEtask(HTASK htask, Etask FAR& etask)
  170. {
  171. thkDebugOut((DEB_DLLS16, "ReleaseEtask on Process (%X) \n", htask));
  172. Assert(etask.m_inits == 1);
  173. Assert(etask.m_oleinits == 0);
  174. Assert(etask.m_reserved == 0);
  175. // Release any state that may have been set
  176. if (etask.m_punkState != NULL && IsValidInterface(etask.m_punkState))
  177. {
  178. etask.m_punkState->Release();
  179. #ifdef _CHICAGO_
  180. if (!LookupEtask(htask, etask))
  181. return;
  182. #endif
  183. }
  184. // first delete all task memory items
  185. delete etask.m_pDlls; // task memory
  186. delete etask.m_pMapToServerCO; // task memory
  187. delete etask.m_pMapToHandlerCO; // task memory
  188. delete etask.m_pArraySH; // task memory
  189. Assert(etask.m_pCThrd == NULL); // task memory; must be gone by now
  190. // remove key now that all task memory that will be freed is freed
  191. #ifdef _CHICAGO_
  192. // Note: just null this out
  193. // Key is removed later in RemoveEtask called
  194. etask.m_pDlls = 0;
  195. etask.m_pMapToServerCO = 0;
  196. etask.m_pMapToHandlerCO = 0;
  197. etask.m_pArraySH = 0;
  198. etask.m_pCThrd = 0;
  199. #else
  200. if (htask != NULL) {
  201. v_mapToEtask.RemoveKey(htask);
  202. }
  203. // if no more entries, remove last remaining memory; this prevents
  204. // problems if the dll is not unloaded for some reason before being
  205. // used again.
  206. if (v_mapToEtask.IsEmpty())
  207. v_mapToEtask.RemoveAll();
  208. #endif
  209. // now remove all shared memory (doesn't need access to task pMalloc)
  210. #ifdef NOTYET
  211. if (etask.m_pMallocSBlock != NULL)
  212. etask.m_pMallocSBlock->Release(); // in shared memory
  213. if (etask.m_pMallocPrivate != NULL)
  214. etask.m_pMallocPrivate->Release(); // in shared memory
  215. #endif
  216. #ifndef _CHICAGO_
  217. Assert(etask.m_pMallocShared != NULL);
  218. if (etask.m_pMallocShared->Release() == 0) { // in shared memory
  219. // last use of the shared allocator; set global to null
  220. v_pMallocShared = NULL;
  221. Assert(v_mapToEtask.IsEmpty());
  222. }
  223. CheckIfMapEmpty();
  224. #endif
  225. // finally, release the task memory
  226. Assert(etask.m_pMalloc != NULL);
  227. etask.m_pMalloc->Release(); // in task memory
  228. etask.m_pMalloc = NULL;
  229. thkDebugOut((DEB_DLLS16, "ReleaseEtask (%X) pMalloc(%p)\n", htask, etask.m_pMalloc));
  230. #if defined(_CHICAGO_)
  231. // Note: update the etask now. Will be deleted on
  232. // DllEntryPoint when refcount is zero by Remove Etask.
  233. SetEtask(htask,etask);
  234. #endif
  235. // invalidate cache
  236. v_hTaskCache = NULL;
  237. thkDebugOut((DEB_DLLS16, "ReleaseEtask done on (%X) \n", htask));
  238. }
  239. //+---------------------------------------------------------------------------
  240. //
  241. // Function: RemoveEtask
  242. //
  243. // Synopsis: Releases the shares allocator and removes
  244. // the etask from the global list
  245. //
  246. // Arguments: [hTask] -- htask
  247. // [etask] -- etask
  248. //
  249. // Returns:
  250. //
  251. // History: 2-03-95 JohannP (Johann Posch) Created
  252. //
  253. // Notes: Called only by Chicago.
  254. //
  255. //----------------------------------------------------------------------------
  256. STDAPI_(BOOL) RemoveEtask(HTASK FAR& hTask, Etask FAR& etask)
  257. {
  258. hTask = GetCurrentProcess();
  259. thkDebugOut((DEB_DLLS16, "RemoveEtask on Process (%X) \n", hTask));
  260. if (hTask == v_hTaskCache)
  261. {
  262. v_hTaskCache = NULL;
  263. }
  264. v_mapToEtask.RemoveKey(hTask);
  265. if (v_mapToEtask.IsEmpty())
  266. v_mapToEtask.RemoveAll();
  267. thkAssert(etask.m_pMallocShared != NULL);
  268. if(etask.m_pMallocShared->Release() == 0)
  269. {
  270. // in shared memory
  271. // last use of the shared allocator; set global to null
  272. v_pMallocShared = NULL;
  273. thkDebugOut((DEB_DLLS16, "RemoveEtask Set v_pMallocShared to NULL (%X) \n", hTask));
  274. Assert(v_mapToEtask.IsEmpty());
  275. }
  276. CheckIfMapEmpty();
  277. thkDebugOut((DEB_DLLS16, "RemoveEtask done (%X) \n", hTask));
  278. return TRUE;
  279. }