primpl.h 73 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150
  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef primpl_h___
  6. #define primpl_h___
  7. #if defined(_PR_PTHREADS)
  8. #include <pthread.h>
  9. #endif
  10. #ifdef WIN32
  11. /*
  12. * Allow use of functions and symbols first defined in Win2k.
  13. */
  14. #if !defined(WINVER) || (WINVER < 0x0500)
  15. #undef WINVER
  16. #define WINVER 0x0500
  17. #endif
  18. #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
  19. #undef _WIN32_WINNT
  20. #define _WIN32_WINNT 0x0500
  21. #endif
  22. #endif /* WIN32 */
  23. #include "nspr.h"
  24. #include "prpriv.h"
  25. typedef struct PRSegment PRSegment;
  26. #include "md/prosdep.h"
  27. #include "obsolete/probslet.h"
  28. #ifdef _PR_HAVE_POSIX_SEMAPHORES
  29. #include <semaphore.h>
  30. #elif defined(_PR_HAVE_SYSV_SEMAPHORES)
  31. #include <sys/sem.h>
  32. #endif
  33. #ifdef HAVE_SYSCALL
  34. #include <sys/syscall.h>
  35. #endif
  36. /*************************************************************************
  37. ***** A Word about Model Dependent Function Naming Convention ***********
  38. *************************************************************************/
  39. /*
  40. NSPR 2.0 must implement its function across a range of platforms
  41. including: MAC, Windows/16, Windows/95, Windows/NT, and several
  42. variants of Unix. Each implementation shares common code as well
  43. as having platform dependent portions. This standard describes how
  44. the model dependent portions are to be implemented.
  45. In header file pr/include/primpl.h, each publicly declared
  46. platform dependent function is declared as:
  47. NSPR_API void _PR_MD_FUNCTION( long arg1, long arg2 );
  48. #define _PR_MD_FUNCTION _MD_FUNCTION
  49. In header file pr/include/md/<platform>/_<platform>.h,
  50. each #define'd macro is redefined as one of:
  51. #define _MD_FUNCTION <blanks>
  52. #define _MD_FUNCTION <expanded macro>
  53. #define _MD_FUNCTION <osFunction>
  54. #define _MD_FUNCTION <_MD_Function>
  55. Where:
  56. <blanks> is no definition at all. In this case, the function is not implemented
  57. and is never called for this platform.
  58. For example:
  59. #define _MD_INIT_CPUS()
  60. <expanded macro> is a C language macro expansion.
  61. For example:
  62. #define _MD_CLEAN_THREAD(_thread) \
  63. PR_BEGIN_MACRO \
  64. PR_DestroyCondVar(_thread->md.asyncIOCVar); \
  65. PR_DestroyLock(_thread->md.asyncIOLock); \
  66. PR_END_MACRO
  67. <osFunction> is some function implemented by the host operating system.
  68. For example:
  69. #define _MD_EXIT exit
  70. <_MD_function> is the name of a function implemented for this platform in
  71. pr/src/md/<platform>/<soruce>.c file.
  72. For example:
  73. #define _MD_GETFILEINFO _MD_GetFileInfo
  74. In <source>.c, the implementation is:
  75. PR_IMPLEMENT(PRInt32) _MD_GetFileInfo(const char *fn, PRFileInfo *info);
  76. */
  77. PR_BEGIN_EXTERN_C
  78. typedef struct _MDLock _MDLock;
  79. typedef struct _MDCVar _MDCVar;
  80. typedef struct _MDSegment _MDSegment;
  81. typedef struct _MDThread _MDThread;
  82. typedef struct _MDThreadStack _MDThreadStack;
  83. typedef struct _MDSemaphore _MDSemaphore;
  84. typedef struct _MDDir _MDDir;
  85. #ifdef MOZ_UNICODE
  86. typedef struct _MDDirUTF16 _MDDirUTF16;
  87. #endif /* MOZ_UNICODE */
  88. typedef struct _MDFileDesc _MDFileDesc;
  89. typedef struct _MDProcess _MDProcess;
  90. typedef struct _MDFileMap _MDFileMap;
  91. #if defined(_PR_PTHREADS)
  92. /*
  93. ** The following definitions are unique to implementing NSPR using pthreads.
  94. ** Since pthreads defines most of the thread and thread synchronization
  95. ** stuff, this is a pretty small set.
  96. */
  97. #define PT_CV_NOTIFIED_LENGTH 6
  98. typedef struct _PT_Notified _PT_Notified;
  99. struct _PT_Notified
  100. {
  101. PRIntn length; /* # of used entries in this structure */
  102. struct
  103. {
  104. PRCondVar *cv; /* the condition variable notified */
  105. PRIntn times; /* and the number of times notified */
  106. } cv[PT_CV_NOTIFIED_LENGTH];
  107. _PT_Notified *link; /* link to another of these | NULL */
  108. };
  109. /*
  110. * bits defined for pthreads 'state' field
  111. */
  112. #define PT_THREAD_DETACHED 0x01 /* thread can't be joined */
  113. #define PT_THREAD_GLOBAL 0x02 /* a global thread (unlikely) */
  114. #define PT_THREAD_SYSTEM 0x04 /* system (not user) thread */
  115. #define PT_THREAD_PRIMORD 0x08 /* this is the primordial thread */
  116. #define PT_THREAD_ABORTED 0x10 /* thread has been interrupted */
  117. #define PT_THREAD_GCABLE 0x20 /* thread is garbage collectible */
  118. #define PT_THREAD_SUSPENDED 0x40 /* thread has been suspended */
  119. #define PT_THREAD_FOREIGN 0x80 /* thread is not one of ours */
  120. #define PT_THREAD_BOUND 0x100 /* a bound-global thread */
  121. #define _PT_THREAD_INTERRUPTED(thr) \
  122. (!(thr->interrupt_blocked) && (thr->state & PT_THREAD_ABORTED))
  123. #define _PT_THREAD_BLOCK_INTERRUPT(thr) \
  124. (thr->interrupt_blocked = 1)
  125. #define _PT_THREAD_UNBLOCK_INTERRUPT(thr) \
  126. (thr->interrupt_blocked = 0)
  127. #define _PT_IS_GCABLE_THREAD(thr) ((thr)->state & PT_THREAD_GCABLE)
  128. /*
  129. ** Possible values for thread's suspend field
  130. ** Note that the first two can be the same as they are really mutually exclusive,
  131. ** i.e. both cannot be happening at the same time. We have two symbolic names
  132. ** just as a mnemonic.
  133. **/
  134. #define PT_THREAD_RESUMED 0x80 /* thread has been resumed */
  135. #define PT_THREAD_SETGCABLE 0x100 /* set the GCAble flag */
  136. #if defined(DEBUG)
  137. typedef struct PTDebug
  138. {
  139. PRTime timeStarted;
  140. PRUintn locks_created, locks_destroyed;
  141. PRUintn locks_acquired, locks_released;
  142. PRUintn cvars_created, cvars_destroyed;
  143. PRUintn cvars_notified, delayed_cv_deletes;
  144. } PTDebug;
  145. #endif /* defined(DEBUG) */
  146. NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
  147. /*
  148. * On Linux and its derivatives POSIX priority scheduling works only for
  149. * real-time threads. On those platforms we set thread's nice values
  150. * instead which requires us to track kernel thread IDs for each POSIX
  151. * thread we create.
  152. */
  153. #if defined(LINUX) && defined(HAVE_SETPRIORITY) && \
  154. ((defined(HAVE_SYSCALL) && defined(SYS_gettid)) || defined(HAVE_GETTID))
  155. #define _PR_NICE_PRIORITY_SCHEDULING
  156. #endif
  157. #else /* defined(_PR_PTHREADS) */
  158. NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
  159. /*
  160. ** This section is contains those parts needed to implement NSPR on
  161. ** platforms in general. One would assume that the pthreads implementation
  162. ** included lots of the same types, at least conceptually.
  163. */
  164. /*
  165. * Local threads only. No multiple CPU support and hence all the
  166. * following routines are no-op.
  167. */
  168. #ifdef _PR_LOCAL_THREADS_ONLY
  169. #define _PR_MD_SUSPEND_THREAD(thread)
  170. #define _PR_MD_RESUME_THREAD(thread)
  171. #define _PR_MD_SUSPEND_CPU(cpu)
  172. #define _PR_MD_RESUME_CPU(cpu)
  173. #define _PR_MD_BEGIN_SUSPEND_ALL()
  174. #define _PR_MD_END_SUSPEND_ALL()
  175. #define _PR_MD_BEGIN_RESUME_ALL()
  176. #define _PR_MD_END_RESUME_ALL()
  177. #define _PR_MD_INIT_ATTACHED_THREAD(thread) PR_FAILURE
  178. #endif
  179. typedef struct _PRCPUQueue _PRCPUQueue;
  180. typedef struct _PRCPU _PRCPU;
  181. typedef struct _MDCPU _MDCPU;
  182. struct _PRCPUQueue {
  183. _MDLock runQLock; /* lock for the run + wait queues */
  184. _MDLock sleepQLock; /* lock for the run + wait queues */
  185. _MDLock miscQLock; /* lock for the run + wait queues */
  186. PRCList runQ[PR_PRIORITY_LAST + 1]; /* run queue for this CPU */
  187. PRUint32 runQReadyMask;
  188. PRCList sleepQ;
  189. PRIntervalTime sleepQmax;
  190. PRCList pauseQ;
  191. PRCList suspendQ;
  192. PRCList waitingToJoinQ;
  193. PRUintn numCPUs; /* number of CPUs using this Q */
  194. };
  195. struct _PRCPU {
  196. PRCList links; /* link list of CPUs */
  197. PRUint32 id; /* id for this CPU */
  198. union {
  199. PRInt32 bits;
  200. PRUint8 missed[4];
  201. } u;
  202. PRIntn where; /* index into u.missed */
  203. PRPackedBool paused; /* cpu is paused */
  204. PRPackedBool exit; /* cpu should exit */
  205. PRThread *thread; /* native thread for this CPUThread */
  206. PRThread *idle_thread; /* user-level idle thread for this CPUThread */
  207. PRIntervalTime last_clock; /* the last time we went into
  208. * _PR_ClockInterrupt() on this CPU
  209. */
  210. _PRCPUQueue *queue;
  211. _MDCPU md;
  212. };
  213. typedef struct _PRInterruptTable {
  214. const char *name;
  215. PRUintn missed_bit;
  216. void (*handler)(void);
  217. } _PRInterruptTable;
  218. #define _PR_CPU_PTR(_qp) \
  219. ((_PRCPU*) ((char*) (_qp) - offsetof(_PRCPU,links)))
  220. #if !defined(WIN32) && !defined(XP_OS2) \
  221. && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY))
  222. #define _MD_GET_ATTACHED_THREAD() (_PR_MD_CURRENT_THREAD())
  223. #endif
  224. #ifdef _PR_LOCAL_THREADS_ONLY
  225. NSPR_API(struct _PRCPU *) _pr_currentCPU;
  226. NSPR_API(PRThread *) _pr_currentThread;
  227. NSPR_API(PRThread *) _pr_lastThread;
  228. NSPR_API(PRInt32) _pr_intsOff;
  229. #define _MD_CURRENT_CPU() (_pr_currentCPU)
  230. #define _MD_SET_CURRENT_CPU(_cpu) (_pr_currentCPU = (_cpu))
  231. #define _MD_CURRENT_THREAD() (_pr_currentThread)
  232. #define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread))
  233. #define _MD_LAST_THREAD() (_pr_lastThread)
  234. #define _MD_SET_LAST_THREAD(t) (_pr_lastThread = t)
  235. #define _MD_GET_INTSOFF() (_pr_intsOff)
  236. #define _MD_SET_INTSOFF(_val) (_pr_intsOff = _val)
  237. /* The unbalanced curly braces in these two macros are intentional */
  238. #define _PR_LOCK_HEAP() { PRIntn _is; if (_pr_currentCPU) _PR_INTSOFF(_is);
  239. #define _PR_UNLOCK_HEAP() if (_pr_currentCPU) _PR_INTSON(_is); }
  240. #endif /* _PR_LOCAL_THREADS_ONLY */
  241. extern PRInt32 _native_threads_only;
  242. #if defined(_PR_GLOBAL_THREADS_ONLY)
  243. #define _MD_GET_INTSOFF() 0
  244. #define _MD_SET_INTSOFF(_val)
  245. #define _PR_INTSOFF(_is)
  246. #define _PR_FAST_INTSON(_is)
  247. #define _PR_INTSON(_is)
  248. #define _PR_THREAD_LOCK(_thread)
  249. #define _PR_THREAD_UNLOCK(_thread)
  250. #define _PR_RUNQ_LOCK(cpu)
  251. #define _PR_RUNQ_UNLOCK(cpu)
  252. #define _PR_SLEEPQ_LOCK(thread)
  253. #define _PR_SLEEPQ_UNLOCK(thread)
  254. #define _PR_MISCQ_LOCK(thread)
  255. #define _PR_MISCQ_UNLOCK(thread)
  256. #define _PR_CPU_LIST_LOCK()
  257. #define _PR_CPU_LIST_UNLOCK()
  258. #define _PR_ADD_RUNQ(_thread, _cpu, _pri)
  259. #define _PR_DEL_RUNQ(_thread)
  260. #define _PR_ADD_SLEEPQ(_thread, _timeout)
  261. #define _PR_DEL_SLEEPQ(_thread, _propogate)
  262. #define _PR_ADD_JOINQ(_thread, _cpu)
  263. #define _PR_DEL_JOINQ(_thread)
  264. #define _PR_ADD_SUSPENDQ(_thread, _cpu)
  265. #define _PR_DEL_SUSPENDQ(_thread)
  266. #define _PR_THREAD_SWITCH_CPU(_thread, _newCPU)
  267. #define _PR_IS_NATIVE_THREAD(thread) 1
  268. #define _PR_IS_NATIVE_THREAD_SUPPORTED() 1
  269. #else
  270. #define _PR_INTSOFF(_is) \
  271. PR_BEGIN_MACRO \
  272. (_is) = _PR_MD_GET_INTSOFF(); \
  273. _PR_MD_SET_INTSOFF(1); \
  274. PR_END_MACRO
  275. #define _PR_FAST_INTSON(_is) \
  276. PR_BEGIN_MACRO \
  277. _PR_MD_SET_INTSOFF(_is); \
  278. PR_END_MACRO
  279. #define _PR_INTSON(_is) \
  280. PR_BEGIN_MACRO \
  281. if ((_is == 0) && (_PR_MD_CURRENT_CPU())->u.bits) \
  282. _PR_IntsOn((_PR_MD_CURRENT_CPU())); \
  283. _PR_MD_SET_INTSOFF(_is); \
  284. PR_END_MACRO
  285. #ifdef _PR_LOCAL_THREADS_ONLY
  286. #define _PR_IS_NATIVE_THREAD(thread) 0
  287. #define _PR_THREAD_LOCK(_thread)
  288. #define _PR_THREAD_UNLOCK(_thread)
  289. #define _PR_RUNQ_LOCK(cpu)
  290. #define _PR_RUNQ_UNLOCK(cpu)
  291. #define _PR_SLEEPQ_LOCK(thread)
  292. #define _PR_SLEEPQ_UNLOCK(thread)
  293. #define _PR_MISCQ_LOCK(thread)
  294. #define _PR_MISCQ_UNLOCK(thread)
  295. #define _PR_CPU_LIST_LOCK()
  296. #define _PR_CPU_LIST_UNLOCK()
  297. #define _PR_ADD_RUNQ(_thread, _cpu, _pri) \
  298. PR_BEGIN_MACRO \
  299. PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \
  300. _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \
  301. PR_END_MACRO
  302. #define _PR_DEL_RUNQ(_thread) \
  303. PR_BEGIN_MACRO \
  304. _PRCPU *_cpu = _thread->cpu; \
  305. PRInt32 _pri = _thread->priority; \
  306. PR_REMOVE_LINK(&(_thread)->links); \
  307. if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \
  308. _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \
  309. PR_END_MACRO
  310. #define _PR_ADD_SLEEPQ(_thread, _timeout) \
  311. _PR_AddSleepQ(_thread, _timeout);
  312. #define _PR_DEL_SLEEPQ(_thread, _propogate) \
  313. _PR_DelSleepQ(_thread, _propogate);
  314. #define _PR_ADD_JOINQ(_thread, _cpu) \
  315. PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu));
  316. #define _PR_DEL_JOINQ(_thread) \
  317. PR_REMOVE_LINK(&(_thread)->links);
  318. #define _PR_ADD_SUSPENDQ(_thread, _cpu) \
  319. PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu));
  320. #define _PR_DEL_SUSPENDQ(_thread) \
  321. PR_REMOVE_LINK(&(_thread)->links);
  322. #define _PR_THREAD_SWITCH_CPU(_thread, _newCPU)
  323. #define _PR_IS_NATIVE_THREAD_SUPPORTED() 0
  324. #else /* _PR_LOCAL_THREADS_ONLY */
  325. /* These are for the "combined" thread model */
  326. #define _PR_THREAD_LOCK(_thread) \
  327. _PR_MD_LOCK(&(_thread)->threadLock);
  328. #define _PR_THREAD_UNLOCK(_thread) \
  329. _PR_MD_UNLOCK(&(_thread)->threadLock);
  330. #define _PR_RUNQ_LOCK(_cpu) \
  331. PR_BEGIN_MACRO \
  332. _PR_MD_LOCK(&(_cpu)->queue->runQLock );\
  333. PR_END_MACRO
  334. #define _PR_RUNQ_UNLOCK(_cpu) \
  335. PR_BEGIN_MACRO \
  336. _PR_MD_UNLOCK(&(_cpu)->queue->runQLock );\
  337. PR_END_MACRO
  338. #define _PR_SLEEPQ_LOCK(_cpu) \
  339. _PR_MD_LOCK(&(_cpu)->queue->sleepQLock );
  340. #define _PR_SLEEPQ_UNLOCK(_cpu) \
  341. _PR_MD_UNLOCK(&(_cpu)->queue->sleepQLock );
  342. #define _PR_MISCQ_LOCK(_cpu) \
  343. _PR_MD_LOCK(&(_cpu)->queue->miscQLock );
  344. #define _PR_MISCQ_UNLOCK(_cpu) \
  345. _PR_MD_UNLOCK(&(_cpu)->queue->miscQLock );
  346. #define _PR_CPU_LIST_LOCK() _PR_MD_LOCK(&_pr_cpuLock)
  347. #define _PR_CPU_LIST_UNLOCK() _PR_MD_UNLOCK(&_pr_cpuLock)
  348. #define QUEUE_RUN 0x1
  349. #define QUEUE_SLEEP 0x2
  350. #define QUEUE_JOIN 0x4
  351. #define QUEUE_SUSPEND 0x8
  352. #define QUEUE_LOCK 0x10
  353. #define _PR_ADD_RUNQ(_thread, _cpu, _pri) \
  354. PR_BEGIN_MACRO \
  355. PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \
  356. _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \
  357. PR_ASSERT((_thread)->queueCount == 0); \
  358. (_thread)->queueCount = QUEUE_RUN; \
  359. PR_END_MACRO
  360. #define _PR_DEL_RUNQ(_thread) \
  361. PR_BEGIN_MACRO \
  362. _PRCPU *_cpu = _thread->cpu; \
  363. PRInt32 _pri = _thread->priority; \
  364. PR_REMOVE_LINK(&(_thread)->links); \
  365. if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \
  366. _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \
  367. PR_ASSERT((_thread)->queueCount == QUEUE_RUN);\
  368. (_thread)->queueCount = 0; \
  369. PR_END_MACRO
  370. #define _PR_ADD_SLEEPQ(_thread, _timeout) \
  371. PR_ASSERT((_thread)->queueCount == 0); \
  372. (_thread)->queueCount = QUEUE_SLEEP; \
  373. _PR_AddSleepQ(_thread, _timeout);
  374. #define _PR_DEL_SLEEPQ(_thread, _propogate) \
  375. PR_ASSERT((_thread)->queueCount == QUEUE_SLEEP);\
  376. (_thread)->queueCount = 0; \
  377. _PR_DelSleepQ(_thread, _propogate);
  378. #define _PR_ADD_JOINQ(_thread, _cpu) \
  379. PR_ASSERT((_thread)->queueCount == 0); \
  380. (_thread)->queueCount = QUEUE_JOIN; \
  381. PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu));
  382. #define _PR_DEL_JOINQ(_thread) \
  383. PR_ASSERT((_thread)->queueCount == QUEUE_JOIN);\
  384. (_thread)->queueCount = 0; \
  385. PR_REMOVE_LINK(&(_thread)->links);
  386. #define _PR_ADD_SUSPENDQ(_thread, _cpu) \
  387. PR_ASSERT((_thread)->queueCount == 0); \
  388. (_thread)->queueCount = QUEUE_SUSPEND; \
  389. PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu));
  390. #define _PR_DEL_SUSPENDQ(_thread) \
  391. PR_ASSERT((_thread)->queueCount == QUEUE_SUSPEND);\
  392. (_thread)->queueCount = 0; \
  393. PR_REMOVE_LINK(&(_thread)->links);
  394. #define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) \
  395. (_thread)->cpu = (_newCPU);
  396. #define _PR_IS_NATIVE_THREAD(thread) (thread->flags & _PR_GLOBAL_SCOPE)
  397. #define _PR_IS_NATIVE_THREAD_SUPPORTED() 1
  398. #endif /* _PR_LOCAL_THREADS_ONLY */
  399. #endif /* _PR_GLOBAL_THREADS_ONLY */
  400. #define _PR_SET_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 1
  401. #define _PR_CLEAR_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 0
  402. extern _PRInterruptTable _pr_interruptTable[];
  403. /* Bits for _pr_interruptState.u.missed[0,1] */
  404. #define _PR_MISSED_CLOCK 0x1
  405. #define _PR_MISSED_IO 0x2
  406. #define _PR_MISSED_CHILD 0x4
  407. extern void _PR_IntsOn(_PRCPU *cpu);
  408. NSPR_API(void) _PR_WakeupCPU(void);
  409. NSPR_API(void) _PR_PauseCPU(void);
  410. /************************************************************************/
  411. #define _PR_LOCK_LOCK(_lock) \
  412. _PR_MD_LOCK(&(_lock)->ilock);
  413. #define _PR_LOCK_UNLOCK(_lock) \
  414. _PR_MD_UNLOCK(&(_lock)->ilock);
  415. extern void _PR_UnblockLockWaiter(PRLock *lock);
  416. extern PRStatus _PR_InitLock(PRLock *lock);
  417. extern void _PR_FreeLock(PRLock *lock);
  418. #define _PR_LOCK_PTR(_qp) \
  419. ((PRLock*) ((char*) (_qp) - offsetof(PRLock,links)))
  420. /************************************************************************/
  421. #define _PR_CVAR_LOCK(_cvar) \
  422. _PR_MD_LOCK(&(_cvar)->ilock);
  423. #define _PR_CVAR_UNLOCK(_cvar) \
  424. _PR_MD_UNLOCK(&(_cvar)->ilock);
  425. extern PRStatus _PR_InitCondVar(PRCondVar *cvar, PRLock *lock);
  426. extern void _PR_FreeCondVar(PRCondVar *cvar);
  427. extern PRStatus _PR_WaitCondVar(
  428. PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout);
  429. extern void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me);
  430. extern PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen);
  431. NSPR_API(void) _PR_Notify(PRMonitor *mon, PRBool all, PRBool sticky);
  432. /* PRThread.flags */
  433. #define _PR_SYSTEM 0x01
  434. #define _PR_INTERRUPT 0x02
  435. #define _PR_ATTACHED 0x04 /* created via PR_AttachThread */
  436. #define _PR_PRIMORDIAL 0x08 /* the thread that called PR_Init */
  437. #define _PR_ON_SLEEPQ 0x10 /* thread is on the sleepQ */
  438. #define _PR_ON_PAUSEQ 0x20 /* thread is on the pauseQ */
  439. #define _PR_SUSPENDING 0x40 /* thread wants to suspend */
  440. #define _PR_GLOBAL_SCOPE 0x80 /* thread is global scope */
  441. #define _PR_IDLE_THREAD 0x200 /* this is an idle thread */
  442. #define _PR_GCABLE_THREAD 0x400 /* this is a collectable thread */
  443. #define _PR_BOUND_THREAD 0x800 /* a bound thread */
  444. #define _PR_INTERRUPT_BLOCKED 0x1000 /* interrupts blocked */
  445. /* PRThread.state */
  446. #define _PR_UNBORN 0
  447. #define _PR_RUNNABLE 1
  448. #define _PR_RUNNING 2
  449. #define _PR_LOCK_WAIT 3
  450. #define _PR_COND_WAIT 4
  451. #define _PR_JOIN_WAIT 5
  452. #define _PR_IO_WAIT 6
  453. #define _PR_SUSPENDED 7
  454. #define _PR_DEAD_STATE 8 /* for debugging */
  455. /* PRThreadStack.flags */
  456. #define _PR_STACK_VM 0x1 /* using vm instead of malloc */
  457. #define _PR_STACK_MAPPED 0x2 /* vm is mapped */
  458. #define _PR_STACK_PRIMORDIAL 0x4 /* stack for primordial thread */
  459. /*
  460. ** If the default stcksize from the client is zero, we need to pick a machine
  461. ** dependent value. This is only for standard user threads. For custom threads,
  462. ** 0 has a special meaning.
  463. ** Adjust stackSize. Round up to a page boundary.
  464. */
  465. #ifndef _MD_MINIMUM_STACK_SIZE
  466. #define _MD_MINIMUM_STACK_SIZE 0
  467. #endif
  468. #if (!defined(HAVE_CUSTOM_USER_THREADS))
  469. #define _PR_ADJUST_STACKSIZE(stackSize) \
  470. PR_BEGIN_MACRO \
  471. if (stackSize == 0) \
  472. stackSize = _MD_DEFAULT_STACK_SIZE; \
  473. if (stackSize < _MD_MINIMUM_STACK_SIZE) \
  474. stackSize = _MD_MINIMUM_STACK_SIZE; \
  475. stackSize = (stackSize + (1 << _pr_pageShift) - 1) >> _pr_pageShift; \
  476. stackSize <<= _pr_pageShift; \
  477. PR_END_MACRO
  478. #else
  479. #define _PR_ADJUST_STACKSIZE(stackSize)
  480. #endif
  481. #define _PR_IS_GCABLE_THREAD(thr) ((thr)->flags & _PR_GCABLE_THREAD)
  482. #define _PR_PENDING_INTERRUPT(thr) \
  483. (!((thr)->flags & _PR_INTERRUPT_BLOCKED) && ((thr)->flags & _PR_INTERRUPT))
  484. #define _PR_THREAD_BLOCK_INTERRUPT(thr) \
  485. (thr->flags |= _PR_INTERRUPT_BLOCKED)
  486. #define _PR_THREAD_UNBLOCK_INTERRUPT(thr) \
  487. (thr->flags &= ~_PR_INTERRUPT_BLOCKED)
  488. #define _PR_THREAD_PTR(_qp) \
  489. ((PRThread*) ((char*) (_qp) - offsetof(PRThread,links)))
  490. #define _PR_ACTIVE_THREAD_PTR(_qp) \
  491. ((PRThread*) ((char*) (_qp) - offsetof(PRThread,active)))
  492. #define _PR_THREAD_CONDQ_PTR(_qp) \
  493. ((PRThread*) ((char*) (_qp) - offsetof(PRThread,waitQLinks)))
  494. #define _PR_THREAD_MD_TO_PTR(_md) \
  495. ((PRThread*) ((char*) (_md) - offsetof(PRThread,md)))
  496. #define _PR_THREAD_STACK_TO_PTR(_stack) \
  497. ((PRThread*) (_stack->thr))
  498. extern PRCList _pr_active_local_threadQ;
  499. extern PRCList _pr_active_global_threadQ;
  500. extern PRCList _pr_cpuQ;
  501. extern _MDLock _pr_cpuLock;
  502. extern PRInt32 _pr_md_idle_cpus;
  503. #define _PR_ACTIVE_LOCAL_THREADQ() _pr_active_local_threadQ
  504. #define _PR_ACTIVE_GLOBAL_THREADQ() _pr_active_global_threadQ
  505. #define _PR_CPUQ() _pr_cpuQ
  506. #define _PR_RUNQ(_cpu) ((_cpu)->queue->runQ)
  507. #define _PR_RUNQREADYMASK(_cpu) ((_cpu)->queue->runQReadyMask)
  508. #define _PR_SLEEPQ(_cpu) ((_cpu)->queue->sleepQ)
  509. #define _PR_SLEEPQMAX(_cpu) ((_cpu)->queue->sleepQmax)
  510. #define _PR_PAUSEQ(_cpu) ((_cpu)->queue->pauseQ)
  511. #define _PR_SUSPENDQ(_cpu) ((_cpu)->queue->suspendQ)
  512. #define _PR_WAITINGTOJOINQ(_cpu) ((_cpu)->queue->waitingToJoinQ)
  513. extern PRUint32 _pr_recycleThreads; /* Flag for behavior on thread cleanup */
  514. extern PRLock *_pr_deadQLock;
  515. extern PRUint32 _pr_numNativeDead;
  516. extern PRUint32 _pr_numUserDead;
  517. extern PRCList _pr_deadNativeQ;
  518. extern PRCList _pr_deadUserQ;
  519. #define _PR_DEADNATIVEQ _pr_deadNativeQ
  520. #define _PR_DEADUSERQ _pr_deadUserQ
  521. #define _PR_DEADQ_LOCK PR_Lock(_pr_deadQLock);
  522. #define _PR_DEADQ_UNLOCK PR_Unlock(_pr_deadQLock);
  523. #define _PR_INC_DEADNATIVE (_pr_numNativeDead++)
  524. #define _PR_DEC_DEADNATIVE (_pr_numNativeDead--)
  525. #define _PR_NUM_DEADNATIVE (_pr_numNativeDead)
  526. #define _PR_INC_DEADUSER (_pr_numUserDead++)
  527. #define _PR_DEC_DEADUSER (_pr_numUserDead--)
  528. #define _PR_NUM_DEADUSER (_pr_numUserDead)
  529. extern PRUint32 _pr_utid;
  530. extern struct _PRCPU *_pr_primordialCPU;
  531. extern PRLock *_pr_activeLock; /* lock for userActive and systemActive */
  532. extern PRInt32 _pr_userActive; /* number of active user threads */
  533. extern PRInt32 _pr_systemActive; /* number of active system threads */
  534. extern PRInt32 _pr_primordialExitCount; /* number of user threads left
  535. * before the primordial thread
  536. * can exit. */
  537. extern PRCondVar *_pr_primordialExitCVar; /* the condition variable for
  538. * notifying the primordial thread
  539. * when all other user threads
  540. * have terminated. */
  541. extern PRUintn _pr_maxPTDs;
  542. extern PRLock *_pr_terminationCVLock;
  543. /*************************************************************************
  544. * Internal routines either called by PR itself or from machine-dependent *
  545. * code. *
  546. *************************************************************************/
  547. extern void _PR_ClockInterrupt(void);
  548. extern void _PR_Schedule(void);
  549. extern void _PR_SetThreadPriority(
  550. PRThread* thread, PRThreadPriority priority);
  551. /***********************************************************************
  552. ** FUNCTION: _PR_NewSegment()
  553. ** DESCRIPTION:
  554. ** Allocate a memory segment. The "size" value is rounded up to the
  555. ** native system page size and a page aligned portion of memory is
  556. ** returned. This memory is not part of the malloc heap. If "vaddr" is
  557. ** not NULL then PR tries to allocate the segment at the desired virtual
  558. ** address.
  559. ** INPUTS: size: size of the desired memory segment
  560. ** vaddr: address at which the newly aquired segment is to be
  561. ** mapped into memory.
  562. ** OUTPUTS: a memory segment is allocated, a PRSegment is allocated
  563. ** RETURN: pointer to PRSegment
  564. ***********************************************************************/
  565. extern PRSegment* _PR_NewSegment(PRUint32 size, void *vaddr);
  566. /***********************************************************************
  567. ** FUNCTION: _PR_DestroySegment()
  568. ** DESCRIPTION:
  569. ** The memory segment and the PRSegment are freed
  570. ** INPUTS: seg: pointer to PRSegment to be freed
  571. ** OUTPUTS: the the PRSegment and its associated memory segment are freed
  572. ** RETURN: void
  573. ***********************************************************************/
  574. extern void _PR_DestroySegment(PRSegment *seg);
  575. extern PRThreadStack * _PR_NewStack(PRUint32 stackSize);
  576. extern void _PR_FreeStack(PRThreadStack *stack);
  577. extern PRBool _PR_NotifyThread (PRThread *thread, PRThread *me);
  578. extern void _PR_NotifyLockedThread (PRThread *thread);
  579. NSPR_API(void) _PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout);
  580. NSPR_API(void) _PR_DelSleepQ(PRThread *thread, PRBool propogate_time);
  581. extern void _PR_AddThreadToRunQ(PRThread *me, PRThread *thread);
  582. NSPR_API(PRThread*) _PR_CreateThread(PRThreadType type,
  583. void (*start)(void *arg),
  584. void *arg,
  585. PRThreadPriority priority,
  586. PRThreadScope scope,
  587. PRThreadState state,
  588. PRUint32 stackSize,
  589. PRUint32 flags);
  590. extern void _PR_NativeDestroyThread(PRThread *thread);
  591. extern void _PR_UserDestroyThread(PRThread *thread);
  592. extern PRThread* _PRI_AttachThread(
  593. PRThreadType type, PRThreadPriority priority,
  594. PRThreadStack *stack, PRUint32 flags);
  595. extern void _PRI_DetachThread(void);
  596. #define _PR_IO_PENDING(_thread) ((_thread)->io_pending)
  597. NSPR_API(void) _PR_MD_INIT_CPUS();
  598. #define _PR_MD_INIT_CPUS _MD_INIT_CPUS
  599. NSPR_API(void) _PR_MD_WAKEUP_CPUS();
  600. #define _PR_MD_WAKEUP_CPUS _MD_WAKEUP_CPUS
  601. /* Interrupts related */
  602. NSPR_API(void) _PR_MD_START_INTERRUPTS(void);
  603. #define _PR_MD_START_INTERRUPTS _MD_START_INTERRUPTS
  604. NSPR_API(void) _PR_MD_STOP_INTERRUPTS(void);
  605. #define _PR_MD_STOP_INTERRUPTS _MD_STOP_INTERRUPTS
  606. NSPR_API(void) _PR_MD_ENABLE_CLOCK_INTERRUPTS(void);
  607. #define _PR_MD_ENABLE_CLOCK_INTERRUPTS _MD_ENABLE_CLOCK_INTERRUPTS
  608. NSPR_API(void) _PR_MD_DISABLE_CLOCK_INTERRUPTS(void);
  609. #define _PR_MD_DISABLE_CLOCK_INTERRUPTS _MD_DISABLE_CLOCK_INTERRUPTS
  610. NSPR_API(void) _PR_MD_BLOCK_CLOCK_INTERRUPTS(void);
  611. #define _PR_MD_BLOCK_CLOCK_INTERRUPTS _MD_BLOCK_CLOCK_INTERRUPTS
  612. NSPR_API(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void);
  613. #define _PR_MD_UNBLOCK_CLOCK_INTERRUPTS _MD_UNBLOCK_CLOCK_INTERRUPTS
  614. /* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and
  615. * awaken a thread which is waiting on a lock or cvar.
  616. */
  617. extern PRStatus _PR_MD_WAIT(PRThread *, PRIntervalTime timeout);
  618. #define _PR_MD_WAIT _MD_WAIT
  619. extern PRStatus _PR_MD_WAKEUP_WAITER(PRThread *);
  620. #define _PR_MD_WAKEUP_WAITER _MD_WAKEUP_WAITER
  621. #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
  622. NSPR_API(void) _PR_MD_CLOCK_INTERRUPT(void);
  623. #define _PR_MD_CLOCK_INTERRUPT _MD_CLOCK_INTERRUPT
  624. #endif
  625. /* Stack debugging */
  626. NSPR_API(void) _PR_MD_INIT_STACK(PRThreadStack *ts, PRIntn redzone);
  627. #define _PR_MD_INIT_STACK _MD_INIT_STACK
  628. NSPR_API(void) _PR_MD_CLEAR_STACK(PRThreadStack* ts);
  629. #define _PR_MD_CLEAR_STACK _MD_CLEAR_STACK
  630. /* CPU related */
  631. NSPR_API(PRInt32) _PR_MD_GET_INTSOFF(void);
  632. #define _PR_MD_GET_INTSOFF _MD_GET_INTSOFF
  633. NSPR_API(void) _PR_MD_SET_INTSOFF(PRInt32 _val);
  634. #define _PR_MD_SET_INTSOFF _MD_SET_INTSOFF
  635. NSPR_API(_PRCPU*) _PR_MD_CURRENT_CPU(void);
  636. #define _PR_MD_CURRENT_CPU _MD_CURRENT_CPU
  637. NSPR_API(void) _PR_MD_SET_CURRENT_CPU(_PRCPU *cpu);
  638. #define _PR_MD_SET_CURRENT_CPU _MD_SET_CURRENT_CPU
  639. NSPR_API(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu);
  640. #define _PR_MD_INIT_RUNNING_CPU _MD_INIT_RUNNING_CPU
  641. /*
  642. * Returns the number of threads awoken or 0 if a timeout occurred;
  643. */
  644. extern PRInt32 _PR_MD_PAUSE_CPU(PRIntervalTime timeout);
  645. #define _PR_MD_PAUSE_CPU _MD_PAUSE_CPU
  646. extern void _PR_MD_CLEANUP_BEFORE_EXIT(void);
  647. #define _PR_MD_CLEANUP_BEFORE_EXIT _MD_CLEANUP_BEFORE_EXIT
  648. extern void _PR_MD_EXIT(PRIntn status);
  649. #define _PR_MD_EXIT _MD_EXIT
  650. /* Locks related */
  651. NSPR_API(void) _PR_MD_INIT_LOCKS(void);
  652. #define _PR_MD_INIT_LOCKS _MD_INIT_LOCKS
  653. NSPR_API(PRStatus) _PR_MD_NEW_LOCK(_MDLock *md);
  654. #define _PR_MD_NEW_LOCK _MD_NEW_LOCK
  655. NSPR_API(void) _PR_MD_FREE_LOCK(_MDLock *md);
  656. #define _PR_MD_FREE_LOCK _MD_FREE_LOCK
  657. NSPR_API(void) _PR_MD_LOCK(_MDLock *md);
  658. #define _PR_MD_LOCK _MD_LOCK
  659. /* Return 0 on success, a nonzero value on failure. */
  660. NSPR_API(PRIntn) _PR_MD_TEST_AND_LOCK(_MDLock *md);
  661. #define _PR_MD_TEST_AND_LOCK _MD_TEST_AND_LOCK
  662. NSPR_API(void) _PR_MD_UNLOCK(_MDLock *md);
  663. #define _PR_MD_UNLOCK _MD_UNLOCK
  664. NSPR_API(void) _PR_MD_IOQ_LOCK(void);
  665. #define _PR_MD_IOQ_LOCK _MD_IOQ_LOCK
  666. NSPR_API(void) _PR_MD_IOQ_UNLOCK(void);
  667. #define _PR_MD_IOQ_UNLOCK _MD_IOQ_UNLOCK
  668. #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
  669. /* Semaphore related -- only for native threads */
  670. #ifdef HAVE_CVAR_BUILT_ON_SEM
  671. NSPR_API(void) _PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value);
  672. #define _PR_MD_NEW_SEM _MD_NEW_SEM
  673. NSPR_API(void) _PR_MD_DESTROY_SEM(_MDSemaphore *md);
  674. #define _PR_MD_DESTROY_SEM _MD_DESTROY_SEM
  675. NSPR_API(PRStatus) _PR_MD_TIMED_WAIT_SEM(
  676. _MDSemaphore *md, PRIntervalTime timeout);
  677. #define _PR_MD_TIMED_WAIT_SEM _MD_TIMED_WAIT_SEM
  678. NSPR_API(PRStatus) _PR_MD_WAIT_SEM(_MDSemaphore *md);
  679. #define _PR_MD_WAIT_SEM _MD_WAIT_SEM
  680. NSPR_API(void) _PR_MD_POST_SEM(_MDSemaphore *md);
  681. #define _PR_MD_POST_SEM _MD_POST_SEM
  682. #endif /* HAVE_CVAR_BUILT_ON_SEM */
  683. #endif
  684. /* Condition Variables related -- only for native threads */
  685. #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
  686. NSPR_API(PRInt32) _PR_MD_NEW_CV(_MDCVar *md);
  687. #define _PR_MD_NEW_CV _MD_NEW_CV
  688. NSPR_API(void) _PR_MD_FREE_CV(_MDCVar *md);
  689. #define _PR_MD_FREE_CV _MD_FREE_CV
  690. NSPR_API(void) _PR_MD_WAIT_CV(
  691. _MDCVar *mdCVar,_MDLock *mdLock,PRIntervalTime timeout);
  692. #define _PR_MD_WAIT_CV _MD_WAIT_CV
  693. NSPR_API(void) _PR_MD_NOTIFY_CV(_MDCVar *md, _MDLock *lock);
  694. #define _PR_MD_NOTIFY_CV _MD_NOTIFY_CV
  695. NSPR_API(void) _PR_MD_NOTIFYALL_CV(_MDCVar *md, _MDLock *lock);
  696. #define _PR_MD_NOTIFYALL_CV _MD_NOTIFYALL_CV
  697. #endif /* _PR_LOCAL_THREADS_ONLY */
  698. /* Threads related */
  699. NSPR_API(PRThread*) _PR_MD_CURRENT_THREAD(void);
  700. #define _PR_MD_CURRENT_THREAD _MD_CURRENT_THREAD
  701. NSPR_API(PRThread*) _PR_MD_GET_ATTACHED_THREAD(void);
  702. #define _PR_MD_GET_ATTACHED_THREAD _MD_GET_ATTACHED_THREAD
  703. NSPR_API(PRThread*) _PR_MD_LAST_THREAD(void);
  704. #define _PR_MD_LAST_THREAD _MD_LAST_THREAD
  705. NSPR_API(void) _PR_MD_SET_CURRENT_THREAD(PRThread *thread);
  706. #define _PR_MD_SET_CURRENT_THREAD _MD_SET_CURRENT_THREAD
  707. NSPR_API(void) _PR_MD_SET_LAST_THREAD(PRThread *thread);
  708. #define _PR_MD_SET_LAST_THREAD _MD_SET_LAST_THREAD
  709. extern PRStatus _PR_MD_INIT_THREAD(PRThread *thread);
  710. #define _PR_MD_INIT_THREAD _MD_INIT_THREAD
  711. extern void _PR_MD_EXIT_THREAD(PRThread *thread);
  712. #define _PR_MD_EXIT_THREAD _MD_EXIT_THREAD
  713. #ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
  714. NSPR_API(PRStatus) _PR_MD_INIT_ATTACHED_THREAD(PRThread *thread);
  715. #define _PR_MD_INIT_ATTACHED_THREAD _MD_INIT_ATTACHED_THREAD
  716. extern void _PR_MD_SUSPEND_THREAD(PRThread *thread);
  717. #define _PR_MD_SUSPEND_THREAD _MD_SUSPEND_THREAD
  718. extern void _PR_MD_RESUME_THREAD(PRThread *thread);
  719. #define _PR_MD_RESUME_THREAD _MD_RESUME_THREAD
  720. extern void _PR_MD_SUSPEND_CPU(_PRCPU *cpu);
  721. #define _PR_MD_SUSPEND_CPU _MD_SUSPEND_CPU
  722. extern void _PR_MD_RESUME_CPU(_PRCPU *cpu);
  723. #define _PR_MD_RESUME_CPU _MD_RESUME_CPU
  724. extern void _PR_MD_BEGIN_SUSPEND_ALL(void);
  725. #define _PR_MD_BEGIN_SUSPEND_ALL _MD_BEGIN_SUSPEND_ALL
  726. extern void _PR_MD_END_SUSPEND_ALL(void);
  727. #define _PR_MD_END_SUSPEND_ALL _MD_END_SUSPEND_ALL
  728. extern void _PR_MD_BEGIN_RESUME_ALL(void);
  729. #define _PR_MD_BEGIN_RESUME_ALL _MD_BEGIN_RESUME_ALL
  730. extern void _PR_MD_END_RESUME_ALL(void);
  731. #define _PR_MD_END_RESUME_ALL _MD_END_RESUME_ALL
  732. #endif /* !_PR_LOCAL_THREADS_ONLY */
  733. extern void _PR_MD_CLEAN_THREAD(PRThread *thread);
  734. #define _PR_MD_CLEAN_THREAD _MD_CLEAN_THREAD
  735. #ifdef HAVE_CUSTOM_USER_THREADS
  736. extern void _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *);
  737. #define _PR_MD_CREATE_PRIMORDIAL_USER_THREAD _MD_CREATE_PRIMORDIAL_USER_THREAD
  738. extern PRThread* _PR_MD_CREATE_USER_THREAD(
  739. PRUint32 stacksize,
  740. void (*start)(void *),
  741. void *arg);
  742. #define _PR_MD_CREATE_USER_THREAD _MD_CREATE_USER_THREAD
  743. #endif
  744. extern PRStatus _PR_MD_CREATE_THREAD(
  745. PRThread *thread,
  746. void (*start) (void *),
  747. PRThreadPriority priority,
  748. PRThreadScope scope,
  749. PRThreadState state,
  750. PRUint32 stackSize);
  751. #define _PR_MD_CREATE_THREAD _MD_CREATE_THREAD
  752. extern void _PR_MD_JOIN_THREAD(_MDThread *md);
  753. #define _PR_MD_JOIN_THREAD _MD_JOIN_THREAD
  754. extern void _PR_MD_END_THREAD(void);
  755. #define _PR_MD_END_THREAD _MD_END_THREAD
  756. extern void _PR_MD_YIELD(void);
  757. #define _PR_MD_YIELD _MD_YIELD
  758. extern void _PR_MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri);
  759. #define _PR_MD_SET_PRIORITY _MD_SET_PRIORITY
  760. extern void _PR_MD_SET_CURRENT_THREAD_NAME(const char *name);
  761. #define _PR_MD_SET_CURRENT_THREAD_NAME _MD_SET_CURRENT_THREAD_NAME
  762. NSPR_API(void) _PR_MD_SUSPENDALL(void);
  763. #define _PR_MD_SUSPENDALL _MD_SUSPENDALL
  764. NSPR_API(void) _PR_MD_RESUMEALL(void);
  765. #define _PR_MD_RESUMEALL _MD_RESUMEALL
  766. extern void _PR_MD_INIT_CONTEXT(
  767. PRThread *thread, char *top, void (*start) (void), PRBool *status);
  768. #define _PR_MD_INIT_CONTEXT _MD_INIT_CONTEXT
  769. extern void _PR_MD_SWITCH_CONTEXT(PRThread *thread);
  770. #define _PR_MD_SWITCH_CONTEXT _MD_SWITCH_CONTEXT
  771. extern void _PR_MD_RESTORE_CONTEXT(PRThread *thread);
  772. #define _PR_MD_RESTORE_CONTEXT _MD_RESTORE_CONTEXT
  773. /* Segment related */
  774. extern void _PR_MD_INIT_SEGS(void);
  775. #define _PR_MD_INIT_SEGS _MD_INIT_SEGS
  776. extern PRStatus _PR_MD_ALLOC_SEGMENT(PRSegment *seg, PRUint32 size, void *vaddr);
  777. #define _PR_MD_ALLOC_SEGMENT _MD_ALLOC_SEGMENT
  778. extern void _PR_MD_FREE_SEGMENT(PRSegment *seg);
  779. #define _PR_MD_FREE_SEGMENT _MD_FREE_SEGMENT
  780. /* Directory enumeration related */
  781. extern PRStatus _PR_MD_OPEN_DIR(_MDDir *md,const char *name);
  782. #define _PR_MD_OPEN_DIR _MD_OPEN_DIR
  783. extern char * _PR_MD_READ_DIR(_MDDir *md, PRIntn flags);
  784. #define _PR_MD_READ_DIR _MD_READ_DIR
  785. extern PRInt32 _PR_MD_CLOSE_DIR(_MDDir *md);
  786. #define _PR_MD_CLOSE_DIR _MD_CLOSE_DIR
  787. /* Named semaphores related */
  788. extern PRSem * _PR_MD_OPEN_SEMAPHORE(
  789. const char *osname, PRIntn flags, PRIntn mode, PRUintn value);
  790. #define _PR_MD_OPEN_SEMAPHORE _MD_OPEN_SEMAPHORE
  791. extern PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem);
  792. #define _PR_MD_WAIT_SEMAPHORE _MD_WAIT_SEMAPHORE
  793. extern PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem);
  794. #define _PR_MD_POST_SEMAPHORE _MD_POST_SEMAPHORE
  795. extern PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem);
  796. #define _PR_MD_CLOSE_SEMAPHORE _MD_CLOSE_SEMAPHORE
  797. extern PRStatus _PR_MD_DELETE_SEMAPHORE(const char *osname);
  798. #define _PR_MD_DELETE_SEMAPHORE _MD_DELETE_SEMAPHORE
  799. /* I/O related */
  800. extern void _PR_MD_INIT_FILEDESC(PRFileDesc *fd);
  801. #define _PR_MD_INIT_FILEDESC _MD_INIT_FILEDESC
  802. extern void _PR_MD_MAKE_NONBLOCK(PRFileDesc *fd);
  803. #define _PR_MD_MAKE_NONBLOCK _MD_MAKE_NONBLOCK
  804. /* File I/O related */
  805. extern PROsfd _PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode);
  806. #define _PR_MD_OPEN _MD_OPEN
  807. extern PROsfd _PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode);
  808. #define _PR_MD_OPEN_FILE _MD_OPEN_FILE
  809. extern PRInt32 _PR_MD_CLOSE_FILE(PROsfd osfd);
  810. #define _PR_MD_CLOSE_FILE _MD_CLOSE_FILE
  811. extern PRInt32 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 amount);
  812. #define _PR_MD_READ _MD_READ
  813. extern PRInt32 _PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 amount);
  814. #define _PR_MD_WRITE _MD_WRITE
  815. extern PRInt32 _PR_MD_WRITEV(
  816. PRFileDesc *fd, const struct PRIOVec *iov,
  817. PRInt32 iov_size, PRIntervalTime timeout);
  818. #define _PR_MD_WRITEV _MD_WRITEV
  819. extern PRInt32 _PR_MD_FSYNC(PRFileDesc *fd);
  820. #define _PR_MD_FSYNC _MD_FSYNC
  821. extern PRInt32 _PR_MD_DELETE(const char *name);
  822. #define _PR_MD_DELETE _MD_DELETE
  823. extern PRInt32 _PR_MD_RENAME(const char *from, const char *to);
  824. #define _PR_MD_RENAME _MD_RENAME
  825. extern PRInt32 _PR_MD_ACCESS(const char *name, PRAccessHow how);
  826. #define _PR_MD_ACCESS _MD_ACCESS
  827. extern PRInt32 _PR_MD_STAT(const char *name, struct stat *buf);
  828. #define _PR_MD_STAT _MD_STAT
  829. extern PRInt32 _PR_MD_MKDIR(const char *name, PRIntn mode);
  830. #define _PR_MD_MKDIR _MD_MKDIR
  831. extern PRInt32 _PR_MD_MAKE_DIR(const char *name, PRIntn mode);
  832. #define _PR_MD_MAKE_DIR _MD_MAKE_DIR
  833. extern PRInt32 _PR_MD_RMDIR(const char *name);
  834. #define _PR_MD_RMDIR _MD_RMDIR
  835. #ifdef MOZ_UNICODE
  836. /* UTF16 File I/O related */
  837. extern PRStatus _PR_MD_OPEN_DIR_UTF16(_MDDirUTF16 *md, const PRUnichar *name);
  838. #define _PR_MD_OPEN_DIR_UTF16 _MD_OPEN_DIR_UTF16
  839. extern PROsfd _PR_MD_OPEN_FILE_UTF16(const PRUnichar *name, PRIntn osflags, PRIntn mode);
  840. #define _PR_MD_OPEN_FILE_UTF16 _MD_OPEN_FILE_UTF16
  841. extern PRUnichar * _PR_MD_READ_DIR_UTF16(_MDDirUTF16 *md, PRIntn flags);
  842. #define _PR_MD_READ_DIR_UTF16 _MD_READ_DIR_UTF16
  843. extern PRInt32 _PR_MD_CLOSE_DIR_UTF16(_MDDirUTF16 *md);
  844. #define _PR_MD_CLOSE_DIR_UTF16 _MD_CLOSE_DIR_UTF16
  845. extern PRInt32 _PR_MD_GETFILEINFO64_UTF16(const PRUnichar *fn, PRFileInfo64 *info);
  846. #define _PR_MD_GETFILEINFO64_UTF16 _MD_GETFILEINFO64_UTF16
  847. #endif /* MOZ_UNICODE */
  848. /* Socket I/O related */
  849. extern void _PR_MD_INIT_IO(void);
  850. #define _PR_MD_INIT_IO _MD_INIT_IO
  851. extern PRInt32 _PR_MD_CLOSE_SOCKET(PROsfd osfd);
  852. #define _PR_MD_CLOSE_SOCKET _MD_CLOSE_SOCKET
  853. extern PRInt32 _PR_MD_CONNECT(
  854. PRFileDesc *fd, const PRNetAddr *addr,
  855. PRUint32 addrlen, PRIntervalTime timeout);
  856. #define _PR_MD_CONNECT _MD_CONNECT
  857. extern PROsfd _PR_MD_ACCEPT(
  858. PRFileDesc *fd, PRNetAddr *addr,
  859. PRUint32 *addrlen, PRIntervalTime timeout);
  860. #define _PR_MD_ACCEPT _MD_ACCEPT
  861. extern PRInt32 _PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen);
  862. #define _PR_MD_BIND _MD_BIND
  863. extern PRInt32 _PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog);
  864. #define _PR_MD_LISTEN _MD_LISTEN
  865. extern PRInt32 _PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how);
  866. #define _PR_MD_SHUTDOWN _MD_SHUTDOWN
  867. extern PRInt32 _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount,
  868. PRIntn flags, PRIntervalTime timeout);
  869. #define _PR_MD_RECV _MD_RECV
  870. extern PRInt32 _PR_MD_SEND(
  871. PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
  872. PRIntervalTime timeout);
  873. #define _PR_MD_SEND _MD_SEND
  874. extern PRInt32 _PR_MD_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock,
  875. PRNetAddr **raddr, void *buf, PRInt32 amount,
  876. PRIntervalTime timeout);
  877. #define _PR_MD_ACCEPT_READ _MD_ACCEPT_READ
  878. #ifdef WIN32
  879. extern PROsfd _PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *addr,
  880. PRUint32 *addrlen, PRIntervalTime timeout,
  881. PRBool fast,
  882. _PR_AcceptTimeoutCallback callback,
  883. void *callbackArg);
  884. extern PRInt32 _PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock,
  885. PRNetAddr **raddr, void *buf, PRInt32 amount,
  886. PRIntervalTime timeout, PRBool fast,
  887. _PR_AcceptTimeoutCallback callback,
  888. void *callbackArg);
  889. extern void _PR_MD_UPDATE_ACCEPT_CONTEXT(PROsfd s, PROsfd ls);
  890. #define _PR_MD_UPDATE_ACCEPT_CONTEXT _MD_UPDATE_ACCEPT_CONTEXT
  891. /*
  892. * The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME.
  893. * We store the value in a PRTime variable for convenience.
  894. * This constant is used by _PR_FileTimeToPRTime().
  895. * This is defined in ntmisc.c
  896. */
  897. extern const PRTime _pr_filetime_offset;
  898. #endif /* WIN32 */
  899. extern PRInt32 _PR_MD_SENDFILE(
  900. PRFileDesc *sock, PRSendFileData *sfd,
  901. PRInt32 flags, PRIntervalTime timeout);
  902. #define _PR_MD_SENDFILE _MD_SENDFILE
  903. extern PRStatus _PR_MD_GETSOCKNAME(
  904. PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen);
  905. #define _PR_MD_GETSOCKNAME _MD_GETSOCKNAME
  906. extern PRStatus _PR_MD_GETPEERNAME(
  907. PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen);
  908. #define _PR_MD_GETPEERNAME _MD_GETPEERNAME
  909. extern PRStatus _PR_MD_GETSOCKOPT(
  910. PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen);
  911. #define _PR_MD_GETSOCKOPT _MD_GETSOCKOPT
  912. extern PRStatus _PR_MD_SETSOCKOPT(
  913. PRFileDesc *fd, PRInt32 level, PRInt32 optname,
  914. const char* optval, PRInt32 optlen);
  915. #define _PR_MD_SETSOCKOPT _MD_SETSOCKOPT
  916. extern PRStatus PR_CALLBACK _PR_SocketGetSocketOption(
  917. PRFileDesc *fd, PRSocketOptionData *data);
  918. extern PRStatus PR_CALLBACK _PR_SocketSetSocketOption(
  919. PRFileDesc *fd, const PRSocketOptionData *data);
  920. extern PRInt32 _PR_MD_RECVFROM(
  921. PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
  922. PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout);
  923. #define _PR_MD_RECVFROM _MD_RECVFROM
  924. extern PRInt32 _PR_MD_SENDTO(
  925. PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
  926. const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout);
  927. #define _PR_MD_SENDTO _MD_SENDTO
  928. #if defined(_WIN64) && defined(WIN95)
  929. extern PRInt32 _PR_MD_TCPSENDTO(
  930. PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
  931. const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout);
  932. #define _PR_MD_TCPSENDTO _MD_TCPSENDTO
  933. #endif
  934. extern PRInt32 _PR_MD_SOCKETPAIR(int af, int type, int flags, PROsfd *osfd);
  935. #define _PR_MD_SOCKETPAIR _MD_SOCKETPAIR
  936. extern PROsfd _PR_MD_SOCKET(int af, int type, int flags);
  937. #define _PR_MD_SOCKET _MD_SOCKET
  938. extern PRInt32 _PR_MD_SOCKETAVAILABLE(PRFileDesc *fd);
  939. #define _PR_MD_SOCKETAVAILABLE _MD_SOCKETAVAILABLE
  940. extern PRInt32 _PR_MD_PIPEAVAILABLE(PRFileDesc *fd);
  941. #define _PR_MD_PIPEAVAILABLE _MD_PIPEAVAILABLE
  942. extern PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds,
  943. PRIntervalTime timeout);
  944. #define _PR_MD_PR_POLL _MD_PR_POLL
  945. /*
  946. * Initialize fd->secret->inheritable for a newly created fd.
  947. * If 'imported' is false, the osfd (i.e., fd->secret->md.osfd)
  948. * was created by NSPR and hence has the OS-dependent default
  949. * inheritable attribute. If 'imported' is true, the osfd was
  950. * not created by NSPR and hence a system call is required to
  951. * query its inheritable attribute. Since we may never need to
  952. * know the inheritable attribute of a fd, a platform may choose
  953. * to initialize fd->secret->inheritable of an imported fd to
  954. * _PR_TRI_UNKNOWN and only pay the cost of the system call
  955. * (in _PR_MD_QUERY_FD_INHERITABLE) when necessary.
  956. */
  957. extern void _PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported);
  958. #define _PR_MD_INIT_FD_INHERITABLE _MD_INIT_FD_INHERITABLE
  959. extern PRStatus _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable);
  960. #define _PR_MD_SET_FD_INHERITABLE _MD_SET_FD_INHERITABLE
  961. #define _PR_PROCESS_TIMEOUT_INTERRUPT_ERRORS(me) \
  962. if (_PR_PENDING_INTERRUPT(me)) { \
  963. me->flags &= ~_PR_INTERRUPT; \
  964. PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); \
  965. } else { \
  966. PR_SetError(PR_IO_TIMEOUT_ERROR, 0); \
  967. }
  968. extern void *_PR_MD_GET_SP(PRThread *thread);
  969. #define _PR_MD_GET_SP _MD_GET_SP
  970. #endif /* defined(_PR_PTHREADS) */
  971. /************************************************************************/
  972. /*************************************************************************
  973. ** The remainder of the definitions are shared by pthreads and the classic
  974. ** NSPR code. These too may be conditionalized.
  975. *************************************************************************/
  976. /************************************************************************/
  977. extern PROffset32 _PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence);
  978. #define _PR_MD_LSEEK _MD_LSEEK
  979. extern PROffset64 _PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence);
  980. #define _PR_MD_LSEEK64 _MD_LSEEK64
  981. extern PRInt32 _PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info);
  982. #define _PR_MD_GETFILEINFO _MD_GETFILEINFO
  983. extern PRInt32 _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info);
  984. #define _PR_MD_GETFILEINFO64 _MD_GETFILEINFO64
  985. extern PRInt32 _PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info);
  986. #define _PR_MD_GETOPENFILEINFO _MD_GETOPENFILEINFO
  987. extern PRInt32 _PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info);
  988. #define _PR_MD_GETOPENFILEINFO64 _MD_GETOPENFILEINFO64
  989. /*****************************************************************************/
  990. /************************** File descriptor caching **************************/
  991. /*****************************************************************************/
  992. extern void _PR_InitFdCache(void);
  993. extern void _PR_CleanupFdCache(void);
  994. extern PRFileDesc *_PR_Getfd(void);
  995. extern void _PR_Putfd(PRFileDesc *fd);
  996. /*
  997. * These flags are used by NSPR temporarily in the poll
  998. * descriptor's out_flags field to record the mapping of
  999. * NSPR's poll flags to the system poll flags.
  1000. *
  1001. * If _PR_POLL_READ_SYS_WRITE bit is set, it means the
  1002. * PR_POLL_READ flag specified by the topmost layer is
  1003. * mapped to the WRITE flag at the system layer. Similarly
  1004. * for the other three _PR_POLL_XXX_SYS_YYY flags. It is
  1005. * assumed that the PR_POLL_EXCEPT flag doesn't get mapped
  1006. * to other flags.
  1007. */
  1008. #define _PR_POLL_READ_SYS_READ 0x1
  1009. #define _PR_POLL_READ_SYS_WRITE 0x2
  1010. #define _PR_POLL_WRITE_SYS_READ 0x4
  1011. #define _PR_POLL_WRITE_SYS_WRITE 0x8
  1012. /*
  1013. ** These methods are coerced into file descriptor methods table
  1014. ** when the intended service is inappropriate for the particular
  1015. ** type of file descriptor.
  1016. */
  1017. extern PRIntn _PR_InvalidInt(void);
  1018. extern PRInt16 _PR_InvalidInt16(void);
  1019. extern PRInt64 _PR_InvalidInt64(void);
  1020. extern PRStatus _PR_InvalidStatus(void);
  1021. extern PRFileDesc *_PR_InvalidDesc(void);
  1022. extern PRIOMethods _pr_faulty_methods;
  1023. /*
  1024. ** The PR_NETADDR_SIZE macro can only be called on a PRNetAddr union
  1025. ** whose 'family' field is set. It returns the size of the union
  1026. ** member corresponding to the specified address family.
  1027. */
  1028. extern PRUintn _PR_NetAddrSize(const PRNetAddr* addr);
  1029. #if defined(_PR_INET6)
  1030. #define PR_NETADDR_SIZE(_addr) _PR_NetAddrSize(_addr)
  1031. #elif defined(_PR_HAVE_MD_SOCKADDR_IN6)
  1032. /*
  1033. ** Under the following conditions:
  1034. ** 1. _PR_INET6 is not defined;
  1035. ** 2. _PR_INET6_PROBE is defined;
  1036. ** 3. struct sockaddr_in6 has nonstandard fields at the end
  1037. ** (e.g., on Solaris 8),
  1038. ** (_addr)->ipv6 is smaller than struct sockaddr_in6, and
  1039. ** hence we can't pass sizeof((_addr)->ipv6) to socket
  1040. ** functions such as connect because they would fail with
  1041. ** EINVAL.
  1042. **
  1043. ** To pass the correct socket address length to socket
  1044. ** functions, define the macro _PR_HAVE_MD_SOCKADDR_IN6 and
  1045. ** define struct _md_sockaddr_in6 to be isomorphic to
  1046. ** struct sockaddr_in6.
  1047. */
  1048. #if defined(XP_UNIX) || defined(XP_OS2)
  1049. #define PR_NETADDR_SIZE(_addr) \
  1050. ((_addr)->raw.family == PR_AF_INET \
  1051. ? sizeof((_addr)->inet) \
  1052. : ((_addr)->raw.family == PR_AF_INET6 \
  1053. ? sizeof(struct _md_sockaddr_in6) \
  1054. : sizeof((_addr)->local)))
  1055. #else
  1056. #define PR_NETADDR_SIZE(_addr) \
  1057. ((_addr)->raw.family == PR_AF_INET \
  1058. ? sizeof((_addr)->inet) \
  1059. : sizeof(struct _md_sockaddr_in6))
  1060. #endif /* defined(XP_UNIX) */
  1061. #else
  1062. #if defined(XP_UNIX) || defined(XP_OS2)
  1063. #define PR_NETADDR_SIZE(_addr) \
  1064. ((_addr)->raw.family == PR_AF_INET \
  1065. ? sizeof((_addr)->inet) \
  1066. : ((_addr)->raw.family == PR_AF_INET6 \
  1067. ? sizeof((_addr)->ipv6) \
  1068. : sizeof((_addr)->local)))
  1069. #else
  1070. #define PR_NETADDR_SIZE(_addr) \
  1071. ((_addr)->raw.family == PR_AF_INET \
  1072. ? sizeof((_addr)->inet) \
  1073. : sizeof((_addr)->ipv6))
  1074. #endif /* defined(XP_UNIX) */
  1075. #endif /* defined(_PR_INET6) */
  1076. extern PRStatus _PR_MapOptionName(
  1077. PRSockOption optname, PRInt32 *level, PRInt32 *name);
  1078. extern void _PR_InitThreads(
  1079. PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs);
  1080. struct PRLock {
  1081. #if defined(_PR_PTHREADS)
  1082. pthread_mutex_t mutex; /* the underlying lock */
  1083. _PT_Notified notified; /* array of conditions notified */
  1084. PRBool locked; /* whether the mutex is locked */
  1085. pthread_t owner; /* if locked, current lock owner */
  1086. #elif defined(_PR_BTHREADS)
  1087. sem_id semaphoreID; /* the underlying lock */
  1088. int32 benaphoreCount; /* number of people in lock */
  1089. thread_id owner; /* current lock owner */
  1090. #else /* not pthreads or Be threads */
  1091. PRCList links; /* linkage for PRThread.lockList */
  1092. struct PRThread *owner; /* current lock owner */
  1093. PRCList waitQ; /* list of threads waiting for lock */
  1094. PRThreadPriority priority; /* priority of lock */
  1095. PRThreadPriority boostPriority; /* boosted priority of lock owner */
  1096. _MDLock ilock; /* Internal Lock to protect user-level fields */
  1097. #endif
  1098. };
  1099. struct PRCondVar {
  1100. PRLock *lock; /* associated lock that protects the condition */
  1101. #if defined(_PR_PTHREADS)
  1102. pthread_cond_t cv; /* underlying pthreads condition */
  1103. PRInt32 notify_pending; /* CV has destroy pending notification */
  1104. #elif defined(_PR_BTHREADS)
  1105. sem_id sem; /* the underlying lock */
  1106. sem_id handshakeSem; /* the lock for 'notify'-threads waiting for confirmation */
  1107. sem_id signalSem; /* the lock for threads waiting for someone to notify */
  1108. volatile int32 nw; /* the number waiting */
  1109. volatile int32 ns; /* the number signalling */
  1110. long signalBenCount; /* the number waiting on the underlying sem */
  1111. #else /* not pthreads or Be threads */
  1112. PRCList condQ; /* Condition variable wait Q */
  1113. _MDLock ilock; /* Internal Lock to protect condQ */
  1114. _MDCVar md;
  1115. #endif
  1116. };
  1117. /************************************************************************/
  1118. struct PRMonitor {
  1119. const char* name; /* monitor name for debugging */
  1120. #if defined(_PR_PTHREADS)
  1121. pthread_mutex_t lock; /* lock is only held when accessing fields
  1122. * of the PRMonitor, instead of being held
  1123. * while the monitor is entered. The only
  1124. * exception is notifyTimes, which is
  1125. * protected by the monitor. */
  1126. pthread_t owner; /* the owner of the monitor or invalid */
  1127. pthread_cond_t entryCV; /* for threads waiting to enter the monitor */
  1128. pthread_cond_t waitCV; /* for threads waiting on the monitor */
  1129. PRInt32 refCount; /* reference count, an atomic variable.
  1130. * PR_NewMonitor adds a reference to the
  1131. * newly created PRMonitor, and
  1132. * PR_DestroyMonitor releases that reference.
  1133. * PR_ExitMonitor adds a reference before
  1134. * unlocking the internal lock if it needs to
  1135. * signal entryCV, and releases the reference
  1136. * after signaling entryCV. */
  1137. #else /* defined(_PR_PTHREADS) */
  1138. PRLock lock; /* lock is only held when accessing fields
  1139. * of the PRMonitor, instead of being held
  1140. * while the monitor is entered. The only
  1141. * exception is notifyTimes, which is
  1142. * protected by the monitor. */
  1143. PRThread *owner; /* the owner of the monitor or invalid */
  1144. PRCondVar entryCV; /* for threads waiting to enter the monitor */
  1145. PRCondVar waitCV; /* for threads waiting on the monitor */
  1146. #endif /* defined(_PR_PTHREADS) */
  1147. PRUint32 entryCount; /* # of times re-entered */
  1148. PRIntn notifyTimes; /* number of pending notifies for waitCV.
  1149. * The special value -1 means a broadcast
  1150. * (PR_NotifyAll). */
  1151. };
  1152. /************************************************************************/
  1153. struct PRSemaphore {
  1154. #if defined(_PR_BTHREADS)
  1155. sem_id sem;
  1156. int32 benaphoreCount;
  1157. #else
  1158. PRCondVar *cvar; /* associated lock and condition variable queue */
  1159. PRUintn count; /* the value of the counting semaphore */
  1160. PRUint32 waiters; /* threads waiting on the semaphore */
  1161. #if defined(_PR_PTHREADS)
  1162. #else /* defined(_PR_PTHREADS) */
  1163. _MDSemaphore md;
  1164. #endif /* defined(_PR_PTHREADS) */
  1165. #endif /* defined(_PR_BTHREADS) */
  1166. };
  1167. /*************************************************************************/
  1168. struct PRSem {
  1169. #ifdef _PR_HAVE_POSIX_SEMAPHORES
  1170. sem_t *sem;
  1171. #elif defined(_PR_HAVE_SYSV_SEMAPHORES)
  1172. int semid;
  1173. #elif defined(WIN32)
  1174. HANDLE sem;
  1175. #else
  1176. PRInt8 notused;
  1177. #endif
  1178. };
  1179. /*************************************************************************/
  1180. struct PRStackStr {
  1181. /* head MUST be at offset 0; assembly language code relies on this */
  1182. #if defined(AIX)
  1183. volatile PRStackElem prstk_head;
  1184. #else
  1185. PRStackElem prstk_head;
  1186. #endif
  1187. PRLock *prstk_lock;
  1188. char *prstk_name;
  1189. };
  1190. /************************************************************************/
  1191. /* XXX this needs to be exported (sigh) */
  1192. struct PRThreadStack {
  1193. PRCList links;
  1194. PRUintn flags;
  1195. char *allocBase; /* base of stack's allocated memory */
  1196. PRUint32 allocSize; /* size of stack's allocated memory */
  1197. char *stackBottom; /* bottom of stack from C's point of view */
  1198. char *stackTop; /* top of stack from C's point of view */
  1199. PRUint32 stackSize; /* size of usable portion of the stack */
  1200. PRSegment *seg;
  1201. PRThread* thr; /* back pointer to thread owning this stack */
  1202. #if defined(_PR_PTHREADS)
  1203. #else /* defined(_PR_PTHREADS) */
  1204. _MDThreadStack md;
  1205. #endif /* defined(_PR_PTHREADS) */
  1206. };
  1207. extern void _PR_DestroyThreadPrivate(PRThread*);
  1208. typedef void (PR_CALLBACK *_PRStartFn)(void *);
  1209. struct PRThread {
  1210. PRUint32 state; /* thread's creation state */
  1211. PRThreadPriority priority; /* apparent priority, loosly defined */
  1212. void *arg; /* argument to the client's entry point */
  1213. _PRStartFn startFunc; /* the root of the client's thread */
  1214. PRThreadStack *stack; /* info about thread's stack (for GC) */
  1215. void *environment; /* pointer to execution environment */
  1216. PRThreadDumpProc dump; /* dump thread info out */
  1217. void *dumpArg; /* argument for the dump function */
  1218. /*
  1219. ** Per thread private data
  1220. */
  1221. PRUint32 tpdLength; /* thread's current vector length */
  1222. void **privateData; /* private data vector or NULL */
  1223. PRErrorCode errorCode; /* current NSPR error code | zero */
  1224. PRInt32 osErrorCode; /* mapping of errorCode | zero */
  1225. PRIntn errorStringLength; /* textLength from last call to PR_SetErrorText() */
  1226. PRInt32 errorStringSize; /* malloc()'d size of buffer | zero */
  1227. char *errorString; /* current error string | NULL */
  1228. char *name; /* thread's name */
  1229. #if defined(_PR_PTHREADS)
  1230. pthread_t id; /* pthread identifier for the thread */
  1231. PRBool idSet; /* whether 'id' has been set. Protected by
  1232. * pt_book.ml. */
  1233. #ifdef _PR_NICE_PRIORITY_SCHEDULING
  1234. pid_t tid; /* Linux-specific kernel thread ID */
  1235. #endif
  1236. PRBool okToDelete; /* ok to delete the PRThread struct? */
  1237. PRCondVar *waiting; /* where the thread is waiting | NULL */
  1238. void *sp; /* recorded sp for garbage collection */
  1239. PRThread *next, *prev; /* simple linked list of all threads */
  1240. PRUint32 suspend; /* used to store suspend and resume flags */
  1241. #ifdef PT_NO_SIGTIMEDWAIT
  1242. pthread_mutex_t suspendResumeMutex;
  1243. pthread_cond_t suspendResumeCV;
  1244. #endif
  1245. PRUint32 interrupt_blocked; /* interrupt blocked */
  1246. struct pollfd *syspoll_list; /* Unix polling list used by PR_Poll */
  1247. PRUint32 syspoll_count; /* number of elements in syspoll_list */
  1248. #if defined(_PR_POLL_WITH_SELECT)
  1249. int *selectfd_list; /* Unix fd's that PR_Poll selects on */
  1250. PRUint32 selectfd_count; /* number of elements in selectfd_list */
  1251. #endif
  1252. #elif defined(_PR_BTHREADS)
  1253. PRUint32 flags;
  1254. _MDThread md;
  1255. PRBool io_pending;
  1256. PRInt32 io_fd;
  1257. PRBool io_suspended;
  1258. #else /* not pthreads or Be threads */
  1259. _MDLock threadLock; /* Lock to protect thread state variables.
  1260. * Protects the following fields:
  1261. * state
  1262. * priority
  1263. * links
  1264. * wait
  1265. * cpu
  1266. */
  1267. PRUint32 queueCount;
  1268. PRUint32 waitCount;
  1269. PRCList active; /* on list of all active threads */
  1270. PRCList links;
  1271. PRCList waitQLinks; /* when thread is PR_Wait'ing */
  1272. PRCList lockList; /* list of locks currently holding */
  1273. PRIntervalTime sleep; /* sleep time when thread is sleeping */
  1274. struct _wait {
  1275. struct PRLock *lock;
  1276. struct PRCondVar *cvar;
  1277. } wait;
  1278. PRUint32 id;
  1279. PRUint32 flags;
  1280. PRUint32 no_sched; /* Don't schedule the thread to run.
  1281. * This flag has relevance only when
  1282. * multiple NSPR CPUs are created.
  1283. * When a thread is de-scheduled, there
  1284. * is a narrow window of time in which
  1285. * the thread is put on the run queue
  1286. * but the scheduler is actually using
  1287. * the stack of this thread. It is safe
  1288. * to run this thread on a different CPU
  1289. * only when its stack is not in use on
  1290. * any other CPU. The no_sched flag is
  1291. * set during this interval to prevent
  1292. * the thread from being scheduled on a
  1293. * different CPU.
  1294. */
  1295. /* thread termination condition variable for join */
  1296. PRCondVar *term;
  1297. _PRCPU *cpu; /* cpu to which this thread is bound */
  1298. PRUint32 threadAllocatedOnStack;/* boolean */
  1299. /* When an async IO is in progress and a second async IO cannot be
  1300. * initiated, the io_pending flag is set to true. Some platforms will
  1301. * not use the io_pending flag. If the io_pending flag is true, then
  1302. * io_fd is the OS-file descriptor on which IO is pending.
  1303. */
  1304. PRBool io_pending;
  1305. PRInt32 io_fd;
  1306. /* If a timeout occurs or if an outstanding IO is interrupted and the
  1307. * OS doesn't support a real cancellation (NT or MAC), then the
  1308. * io_suspended flag will be set to true. The thread will be resumed
  1309. * but may run into trouble issuing additional IOs until the io_pending
  1310. * flag can be cleared
  1311. */
  1312. PRBool io_suspended;
  1313. _MDThread md;
  1314. #endif
  1315. };
  1316. struct PRProcessAttr {
  1317. PRFileDesc *stdinFd;
  1318. PRFileDesc *stdoutFd;
  1319. PRFileDesc *stderrFd;
  1320. char *currentDirectory;
  1321. char *fdInheritBuffer;
  1322. PRSize fdInheritBufferSize;
  1323. PRSize fdInheritBufferUsed;
  1324. };
  1325. struct PRProcess {
  1326. _MDProcess md;
  1327. };
  1328. struct PRFileMap {
  1329. PRFileDesc *fd;
  1330. PRFileMapProtect prot;
  1331. _MDFileMap md;
  1332. };
  1333. /************************************************************************/
  1334. /*
  1335. ** File descriptors of the NSPR layer can be in one of the
  1336. ** following states (stored in the 'state' field of struct
  1337. ** PRFilePrivate):
  1338. ** - _PR_FILEDESC_OPEN: The OS fd is open.
  1339. ** - _PR_FILEDESC_CLOSED: The OS fd is closed. The PRFileDesc
  1340. ** is still open but is unusable. The only operation allowed
  1341. ** on the PRFileDesc is PR_Close().
  1342. ** - _PR_FILEDESC_FREED: The OS fd is closed and the PRFileDesc
  1343. ** structure is freed.
  1344. */
  1345. #define _PR_FILEDESC_OPEN 0xaaaaaaaa /* 1010101... */
  1346. #define _PR_FILEDESC_CLOSED 0x55555555 /* 0101010... */
  1347. #define _PR_FILEDESC_FREED 0x11111111
  1348. /*
  1349. ** A boolean type with an additional "unknown" state
  1350. */
  1351. typedef enum {
  1352. _PR_TRI_TRUE = 1,
  1353. _PR_TRI_FALSE = 0,
  1354. _PR_TRI_UNKNOWN = -1
  1355. } _PRTriStateBool;
  1356. struct PRFilePrivate {
  1357. PRInt32 state;
  1358. PRBool nonblocking;
  1359. _PRTriStateBool inheritable;
  1360. PRFileDesc *next;
  1361. PRIntn lockCount; /* 0: not locked
  1362. * -1: a native lockfile call is in progress
  1363. * > 0: # times the file is locked */
  1364. #ifdef _PR_HAVE_PEEK_BUFFER
  1365. char *peekBuffer;
  1366. PRInt32 peekBufSize;
  1367. PRInt32 peekBytes;
  1368. #endif
  1369. #if !defined(_PR_HAVE_O_APPEND)
  1370. PRBool appendMode; /* Some platforms don't have O_APPEND or its
  1371. * equivalent, so they have to seek to end of
  1372. * file on write if the file was opened in
  1373. * append mode. See Bugzilla 4090, 276330. */
  1374. #endif
  1375. _MDFileDesc md;
  1376. #ifdef _PR_NEED_SECRET_AF
  1377. PRUint16 af; /* If the platform's implementation of accept()
  1378. * requires knowing the address family of the
  1379. * socket, we save the address family here. */
  1380. #endif
  1381. #if defined(_WIN64)
  1382. /* This is necessary for TCP Fast Open. TCP Fast Open in windows must
  1383. * use ConnectEx function which uses OVERLAPPED. TCPSendTo will call
  1384. * ConnectEx to send fast open data. If ConnectEx returns
  1385. * ERROR_IO_PENDING we need to save OVERLAPPED structure and we will
  1386. * use it in ConnectContinue to get the final result of ConnectEx.
  1387. */
  1388. PRBool alreadyConnected;
  1389. PRBool overlappedActive;
  1390. OVERLAPPED ol;
  1391. #endif
  1392. };
  1393. #ifdef _WIN64
  1394. #define PR_PRIdOSFD "lld" /* for printing PROsfd */
  1395. #define PR_PRIxOSFD "llx"
  1396. #define PR_SCNdOSFD "lld" /* for scanning PROsfd */
  1397. #define PR_SCNxOSFD "llx"
  1398. #else
  1399. #define PR_PRIdOSFD "ld" /* for printing PROsfd */
  1400. #define PR_PRIxOSFD "lx"
  1401. #define PR_SCNdOSFD "ld" /* for scanning PROsfd */
  1402. #define PR_SCNxOSFD "lx"
  1403. #endif
  1404. struct PRDir {
  1405. PRDirEntry d;
  1406. _MDDir md;
  1407. };
  1408. #ifdef MOZ_UNICODE
  1409. struct PRDirUTF16 {
  1410. PRDirEntry d;
  1411. _MDDirUTF16 md;
  1412. };
  1413. #endif /* MOZ_UNICODE */
  1414. extern void _PR_InitLocks(void);
  1415. extern void _PR_InitSegs(void);
  1416. extern void _PR_InitStacks(void);
  1417. extern void _PR_InitTPD(void);
  1418. extern void _PR_InitMem(void);
  1419. extern void _PR_InitEnv(void);
  1420. extern void _PR_InitCMon(void);
  1421. extern void _PR_InitIO(void);
  1422. extern void _PR_InitLog(void);
  1423. extern void _PR_InitNet(void);
  1424. extern void _PR_InitClock(void);
  1425. extern void _PR_InitLinker(void);
  1426. extern void _PR_InitAtomic(void);
  1427. extern void _PR_InitCPUs(void);
  1428. extern void _PR_InitDtoa(void);
  1429. extern void _PR_InitTime(void);
  1430. extern void _PR_InitMW(void);
  1431. extern void _PR_InitRWLocks(void);
  1432. extern void _PR_CleanupThread(PRThread *thread);
  1433. extern void _PR_CleanupCallOnce(void);
  1434. extern void _PR_CleanupMW(void);
  1435. extern void _PR_CleanupTime(void);
  1436. extern void _PR_CleanupDtoa(void);
  1437. extern void _PR_ShutdownLinker(void);
  1438. extern void _PR_CleanupEnv(void);
  1439. extern void _PR_CleanupIO(void);
  1440. extern void _PR_CleanupCMon(void);
  1441. extern void _PR_CleanupNet(void);
  1442. extern void _PR_CleanupLayerCache(void);
  1443. extern void _PR_CleanupStacks(void);
  1444. #ifdef WINNT
  1445. extern void _PR_CleanupCPUs(void);
  1446. #endif
  1447. extern void _PR_CleanupThreads(void);
  1448. extern void _PR_CleanupTPD(void);
  1449. extern void _PR_Cleanup(void);
  1450. extern void _PR_LogCleanup(void);
  1451. extern void _PR_InitLayerCache(void);
  1452. extern PRBool _pr_initialized;
  1453. extern void _PR_ImplicitInitialization(void);
  1454. extern PRBool _PR_Obsolete(const char *obsolete, const char *preferred);
  1455. /************************************************************************/
  1456. struct PRSegment {
  1457. void *vaddr;
  1458. PRUint32 size;
  1459. PRUintn flags;
  1460. #if defined(_PR_PTHREADS)
  1461. #else /* defined(_PR_PTHREADS) */
  1462. _MDSegment md;
  1463. #endif /* defined(_PR_PTHREADS) */
  1464. };
  1465. /* PRSegment.flags */
  1466. #define _PR_SEG_VM 0x1
  1467. /************************************************************************/
  1468. extern PRInt32 _pr_pageSize;
  1469. extern PRInt32 _pr_pageShift;
  1470. extern PRLogModuleInfo *_pr_clock_lm;
  1471. extern PRLogModuleInfo *_pr_cmon_lm;
  1472. extern PRLogModuleInfo *_pr_io_lm;
  1473. extern PRLogModuleInfo *_pr_cvar_lm;
  1474. extern PRLogModuleInfo *_pr_mon_lm;
  1475. extern PRLogModuleInfo *_pr_linker_lm;
  1476. extern PRLogModuleInfo *_pr_sched_lm;
  1477. extern PRLogModuleInfo *_pr_thread_lm;
  1478. extern PRLogModuleInfo *_pr_gc_lm;
  1479. extern PRFileDesc *_pr_stdin;
  1480. extern PRFileDesc *_pr_stdout;
  1481. extern PRFileDesc *_pr_stderr;
  1482. /* Zone allocator */
  1483. /*
  1484. ** The zone allocator code has hardcoded pthread types and
  1485. ** functions, so it can only be used in the pthreads version.
  1486. ** This can be fixed by replacing the hardcoded pthread types
  1487. ** and functions with macros that expand to the native thread
  1488. ** types and functions on each platform.
  1489. */
  1490. #if defined(_PR_PTHREADS)
  1491. #define _PR_ZONE_ALLOCATOR
  1492. #endif
  1493. #ifdef _PR_ZONE_ALLOCATOR
  1494. extern void _PR_InitZones(void);
  1495. extern void _PR_DestroyZones(void);
  1496. #endif
  1497. /* Overriding malloc, free, etc. */
  1498. #if !defined(_PR_NO_PREEMPT) && defined(XP_UNIX) \
  1499. && !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY) \
  1500. && !defined(PURIFY) \
  1501. && !defined(DARWIN) \
  1502. && !defined(QNX) \
  1503. && !(defined (UNIXWARE) && defined (USE_SVR4_THREADS))
  1504. #define _PR_OVERRIDE_MALLOC
  1505. #endif
  1506. /*************************************************************************
  1507. * External machine-dependent code provided by each OS. * *
  1508. *************************************************************************/
  1509. /* Initialization related */
  1510. extern void _PR_MD_EARLY_INIT(void);
  1511. #define _PR_MD_EARLY_INIT _MD_EARLY_INIT
  1512. extern void _PR_MD_INTERVAL_INIT(void);
  1513. #define _PR_MD_INTERVAL_INIT _MD_INTERVAL_INIT
  1514. NSPR_API(void) _PR_MD_FINAL_INIT(void);
  1515. #define _PR_MD_FINAL_INIT _MD_FINAL_INIT
  1516. extern void _PR_MD_EARLY_CLEANUP(void);
  1517. #define _PR_MD_EARLY_CLEANUP _MD_EARLY_CLEANUP
  1518. /* Process control */
  1519. extern PRProcess * _PR_MD_CREATE_PROCESS(
  1520. const char *path,
  1521. char *const *argv,
  1522. char *const *envp,
  1523. const PRProcessAttr *attr);
  1524. #define _PR_MD_CREATE_PROCESS _MD_CREATE_PROCESS
  1525. extern PRStatus _PR_MD_DETACH_PROCESS(PRProcess *process);
  1526. #define _PR_MD_DETACH_PROCESS _MD_DETACH_PROCESS
  1527. extern PRStatus _PR_MD_WAIT_PROCESS(PRProcess *process, PRInt32 *exitCode);
  1528. #define _PR_MD_WAIT_PROCESS _MD_WAIT_PROCESS
  1529. extern PRStatus _PR_MD_KILL_PROCESS(PRProcess *process);
  1530. #define _PR_MD_KILL_PROCESS _MD_KILL_PROCESS
  1531. /* Current Time */
  1532. NSPR_API(PRTime) _PR_MD_NOW(void);
  1533. #define _PR_MD_NOW _MD_NOW
  1534. /* Environment related */
  1535. extern char* _PR_MD_GET_ENV(const char *name);
  1536. #define _PR_MD_GET_ENV _MD_GET_ENV
  1537. extern PRIntn _PR_MD_PUT_ENV(const char *name);
  1538. #define _PR_MD_PUT_ENV _MD_PUT_ENV
  1539. /* Atomic operations */
  1540. extern void _PR_MD_INIT_ATOMIC(void);
  1541. #define _PR_MD_INIT_ATOMIC _MD_INIT_ATOMIC
  1542. extern PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *);
  1543. #define _PR_MD_ATOMIC_INCREMENT _MD_ATOMIC_INCREMENT
  1544. extern PRInt32 _PR_MD_ATOMIC_ADD(PRInt32 *, PRInt32);
  1545. #define _PR_MD_ATOMIC_ADD _MD_ATOMIC_ADD
  1546. extern PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *);
  1547. #define _PR_MD_ATOMIC_DECREMENT _MD_ATOMIC_DECREMENT
  1548. extern PRInt32 _PR_MD_ATOMIC_SET(PRInt32 *, PRInt32);
  1549. #define _PR_MD_ATOMIC_SET _MD_ATOMIC_SET
  1550. /* Garbage collection */
  1551. /*
  1552. ** Save the registers that the GC would find interesting into the thread
  1553. ** "t". isCurrent will be non-zero if the thread state that is being
  1554. ** saved is the currently executing thread. Return the address of the
  1555. ** first register to be scanned as well as the number of registers to
  1556. ** scan in "np".
  1557. **
  1558. ** If "isCurrent" is non-zero then it is allowed for the thread context
  1559. ** area to be used as scratch storage to hold just the registers
  1560. ** necessary for scanning.
  1561. */
  1562. extern PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np);
  1563. /* Time intervals */
  1564. extern PRIntervalTime _PR_MD_GET_INTERVAL(void);
  1565. #define _PR_MD_GET_INTERVAL _MD_GET_INTERVAL
  1566. extern PRIntervalTime _PR_MD_INTERVAL_PER_SEC(void);
  1567. #define _PR_MD_INTERVAL_PER_SEC _MD_INTERVAL_PER_SEC
  1568. /* Affinity masks */
  1569. extern PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask );
  1570. #define _PR_MD_SETTHREADAFFINITYMASK _MD_SETTHREADAFFINITYMASK
  1571. extern PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask);
  1572. #define _PR_MD_GETTHREADAFFINITYMASK _MD_GETTHREADAFFINITYMASK
  1573. /* File locking */
  1574. extern PRStatus _PR_MD_LOCKFILE(PROsfd osfd);
  1575. #define _PR_MD_LOCKFILE _MD_LOCKFILE
  1576. extern PRStatus _PR_MD_TLOCKFILE(PROsfd osfd);
  1577. #define _PR_MD_TLOCKFILE _MD_TLOCKFILE
  1578. extern PRStatus _PR_MD_UNLOCKFILE(PROsfd osfd);
  1579. #define _PR_MD_UNLOCKFILE _MD_UNLOCKFILE
  1580. /* Memory-mapped files */
  1581. extern PRStatus _PR_MD_CREATE_FILE_MAP(PRFileMap *fmap, PRInt64 size);
  1582. #define _PR_MD_CREATE_FILE_MAP _MD_CREATE_FILE_MAP
  1583. extern PRInt32 _PR_MD_GET_MEM_MAP_ALIGNMENT(void);
  1584. #define _PR_MD_GET_MEM_MAP_ALIGNMENT _MD_GET_MEM_MAP_ALIGNMENT
  1585. extern void * _PR_MD_MEM_MAP(
  1586. PRFileMap *fmap,
  1587. PROffset64 offset,
  1588. PRUint32 len);
  1589. #define _PR_MD_MEM_MAP _MD_MEM_MAP
  1590. extern PRStatus _PR_MD_MEM_UNMAP(void *addr, PRUint32 size);
  1591. #define _PR_MD_MEM_UNMAP _MD_MEM_UNMAP
  1592. extern PRStatus _PR_MD_CLOSE_FILE_MAP(PRFileMap *fmap);
  1593. #define _PR_MD_CLOSE_FILE_MAP _MD_CLOSE_FILE_MAP
  1594. extern PRStatus _PR_MD_SYNC_MEM_MAP(
  1595. PRFileDesc *fd,
  1596. void *addr,
  1597. PRUint32 len);
  1598. #define _PR_MD_SYNC_MEM_MAP _MD_SYNC_MEM_MAP
  1599. /* Named Shared Memory */
  1600. /*
  1601. ** Declare PRSharedMemory.
  1602. */
  1603. struct PRSharedMemory
  1604. {
  1605. char *ipcname; /* after conversion to native */
  1606. PRSize size; /* from open */
  1607. PRIntn mode; /* from open */
  1608. PRIntn flags; /* from open */
  1609. #if defined(PR_HAVE_POSIX_NAMED_SHARED_MEMORY)
  1610. int id;
  1611. #elif defined(PR_HAVE_SYSV_NAMED_SHARED_MEMORY)
  1612. int id;
  1613. #elif defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY)
  1614. HANDLE handle;
  1615. #else
  1616. PRUint32 nothing; /* placeholder, nothing behind here */
  1617. #endif
  1618. PRUint32 ident; /* guard word at end of struct */
  1619. #define _PR_SHM_IDENT 0xdeadbad
  1620. };
  1621. extern PRSharedMemory * _MD_OpenSharedMemory(
  1622. const char *name,
  1623. PRSize size,
  1624. PRIntn flags,
  1625. PRIntn mode
  1626. );
  1627. #define _PR_MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory
  1628. extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags );
  1629. #define _PR_MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory
  1630. extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr );
  1631. #define _PR_MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory
  1632. extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm );
  1633. #define _PR_MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory
  1634. extern PRStatus _MD_DeleteSharedMemory( const char *name );
  1635. #define _PR_MD_DELETE_SHARED_MEMORY _MD_DeleteSharedMemory
  1636. extern PRFileMap* _md_OpenAnonFileMap(
  1637. const char *dirName,
  1638. PRSize size,
  1639. PRFileMapProtect prot
  1640. );
  1641. #define _PR_MD_OPEN_ANON_FILE_MAP _md_OpenAnonFileMap
  1642. extern PRStatus _md_ExportFileMapAsString(
  1643. PRFileMap *fm,
  1644. PRSize bufSize,
  1645. char *buf
  1646. );
  1647. #define _PR_MD_EXPORT_FILE_MAP_AS_STRING _md_ExportFileMapAsString
  1648. extern PRFileMap * _md_ImportFileMapFromString(
  1649. const char *fmstring
  1650. );
  1651. #define _PR_MD_IMPORT_FILE_MAP_FROM_STRING _md_ImportFileMapFromString
  1652. /* Interprocess communications (IPC) */
  1653. /*
  1654. * The maximum length of an NSPR IPC name, including the
  1655. * terminating null byte.
  1656. */
  1657. #define PR_IPC_NAME_SIZE 1024
  1658. /*
  1659. * Types of NSPR IPC objects
  1660. */
  1661. typedef enum {
  1662. _PRIPCSem, /* semaphores */
  1663. _PRIPCShm /* shared memory segments */
  1664. } _PRIPCType;
  1665. /*
  1666. * Make a native IPC name from an NSPR IPC name.
  1667. */
  1668. extern PRStatus _PR_MakeNativeIPCName(
  1669. const char *name, /* NSPR IPC name */
  1670. char *result, /* result buffer */
  1671. PRIntn size, /* size of result buffer */
  1672. _PRIPCType type /* type of IPC object */
  1673. );
  1674. /* Socket call error code */
  1675. NSPR_API(PRInt32) _PR_MD_GET_SOCKET_ERROR(void);
  1676. #define _PR_MD_GET_SOCKET_ERROR _MD_GET_SOCKET_ERROR
  1677. /* Get name of current host */
  1678. extern PRStatus _PR_MD_GETHOSTNAME(char *name, PRUint32 namelen);
  1679. #define _PR_MD_GETHOSTNAME _MD_GETHOSTNAME
  1680. extern PRStatus _PR_MD_GETSYSINFO(PRSysInfo cmd, char *name, PRUint32 namelen);
  1681. #define _PR_MD_GETSYSINFO _MD_GETSYSINFO
  1682. /* File descriptor inheritance */
  1683. /*
  1684. * If fd->secret->inheritable is _PR_TRI_UNKNOWN and we need to
  1685. * know the inheritable attribute of the fd, call this function
  1686. * to find that out. This typically requires a system call.
  1687. */
  1688. extern void _PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd);
  1689. #define _PR_MD_QUERY_FD_INHERITABLE _MD_QUERY_FD_INHERITABLE
  1690. /* --- PR_GetRandomNoise() related things --- */
  1691. extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size );
  1692. #define _PR_MD_GET_RANDOM_NOISE(buf,size) _PR_MD_GetRandomNoise((buf),(size))
  1693. extern PRSize _pr_CopyLowBits( void *dest, PRSize dstlen, void *src, PRSize srclen );
  1694. /* end PR_GetRandomNoise() related */
  1695. #if defined(_WIN64) && defined(WIN95)
  1696. typedef struct _PRFileDescList {
  1697. PRFileDesc *fd;
  1698. struct _PRFileDescList *next;
  1699. } PRFileDescList;
  1700. extern PRLock *_fd_waiting_for_overlapped_done_lock;
  1701. extern PRFileDescList *_fd_waiting_for_overlapped_done;
  1702. extern void CheckOverlappedPendingSocketsAreDone();
  1703. #endif
  1704. PR_END_EXTERN_C
  1705. #endif /* primpl_h___ */