Notifier.3
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:27k
源码类别:

通讯编程

开发平台:

Visual C++

  1. '"
  2. '" Copyright (c) 1998-1999 Scriptics Corporation
  3. '" Copyright (c) 1995-1997 Sun Microsystems, Inc.
  4. '"
  5. '" See the file "license.terms" for information on usage and redistribution
  6. '" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  7. '" 
  8. '" RCS: @(#) $Id: Notifier.3,v 1.9.2.1 2004/11/25 15:28:37 vasiljevic Exp $
  9. '" 
  10. .so man.macros
  11. .TH Notifier 3 8.1 Tcl "Tcl Library Procedures"
  12. .BS
  13. .SH NAME
  14. Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime, Tcl_QueueEvent, Tcl_ThreadQueueEvent, Tcl_ThreadAlert, Tcl_GetCurrentThread, Tcl_DeleteEvents, Tcl_InitNotifier, Tcl_FinalizeNotifier, Tcl_WaitForEvent, Tcl_AlertNotifier, Tcl_SetTimer, Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetServiceMode - the event queue and notifier interfaces
  15. .SH SYNOPSIS
  16. .nf
  17. fB#include <tcl.h>fR
  18. .sp
  19. void
  20. fBTcl_CreateEventSourcefR(fIsetupProc, checkProc, clientDatafR)
  21. .sp
  22. void
  23. fBTcl_DeleteEventSourcefR(fIsetupProc, checkProc, clientDatafR)
  24. .sp
  25. void
  26. fBTcl_SetMaxBlockTimefR(fItimePtrfR)
  27. .sp
  28. void
  29. fBTcl_QueueEventfR(fIevPtr, positionfR)
  30. .VS 8.1
  31. .sp
  32. void
  33. fBTcl_ThreadQueueEventfR(fIthreadId, evPtr, positionfR)
  34. .sp
  35. void
  36. fBTcl_ThreadAlertfR(fIthreadIdfR)
  37. .sp
  38. Tcl_ThreadId
  39. fBTcl_GetCurrentThreadfR()
  40. .sp
  41. void
  42. fBTcl_DeleteEventsfR(fIdeleteProc, clientDatafR)
  43. .sp
  44. ClientData
  45. fBTcl_InitNotifierfR()
  46. .sp
  47. void
  48. fBTcl_FinalizeNotifierfR(fIclientDatafR)
  49. .sp
  50. int
  51. fBTcl_WaitForEventfR(fItimePtrfR)
  52. .sp
  53. void
  54. fBTcl_AlertNotifierfR(fIclientDatafR)
  55. .sp
  56. void
  57. fBTcl_SetTimerfR(fItimePtrfR)
  58. .sp
  59. int
  60. fBTcl_ServiceAllfR()
  61. .sp
  62. int
  63. fBTcl_ServiceEventfR(fIflagsfR)
  64. .sp
  65. int
  66. fBTcl_GetServiceModefR()
  67. .sp
  68. int
  69. fBTcl_SetServiceModefR(fImodefR)
  70. .VE
  71. .SH ARGUMENTS
  72. .AS Tcl_EventDeleteProc milliseconds
  73. .AP Tcl_EventSetupProc *setupProc in
  74. Procedure to invoke to prepare for event wait in fBTcl_DoOneEventfR.
  75. .AP Tcl_EventCheckProc *checkProc in
  76. Procedure for fBTcl_DoOneEventfR to invoke after waiting for
  77. events.  Checks to see if any events have occurred and, if so,
  78. queues them.
  79. .AP ClientData clientData in
  80. Arbitrary one-word value to pass to fIsetupProcfR, fIcheckProcfR, or
  81. fIdeleteProcfR.
  82. .AP Tcl_Time *timePtr in
  83. Indicates the maximum amount of time to wait for an event.  This
  84. is specified as an interval (how long to wait), not an absolute
  85. time (when to wakeup).  If the pointer passed to fBTcl_WaitForEventfR
  86. is NULL, it means there is no maximum wait time:  wait forever if
  87. necessary.
  88. .AP Tcl_Event *evPtr in
  89. An event to add to the event queue.  The storage for the event must
  90. have been allocated by the caller using fBTcl_AllocfR or fBckallocfR.
  91. .AP Tcl_QueuePosition position in
  92. Where to add the new event in the queue:  fBTCL_QUEUE_TAILfR,
  93. fBTCL_QUEUE_HEADfR, or fBTCL_QUEUE_MARKfR.
  94. .AP Tcl_ThreadId threadId in
  95. A unique identifier for a thread.
  96. .AP Tcl_EventDeleteProc *deleteProc in
  97. Procedure to invoke for each queued event in fBTcl_DeleteEventsfR.
  98. .AP int flags in
  99. What types of events to service.  These flags are the same as those
  100. passed to fBTcl_DoOneEventfR.
  101. .VS 8.1
  102. .AP int mode in
  103. Indicates whether events should be serviced by fBTcl_ServiceAllfR.
  104. Must be one of fBTCL_SERVICE_NONEfR or fBTCL_SERVICE_ALLfR.
  105. .VE
  106. .BE
  107. .SH INTRODUCTION
  108. .PP
  109. The interfaces described here are used to customize the Tcl event
  110. loop.  The two most common customizations are to add new sources of
  111. events and to merge Tcl's event loop with some other event loop, such
  112. as one provided by an application in which Tcl is embedded.  Each of
  113. these tasks is described in a separate section below.
  114. .PP
  115. The procedures in this manual entry are the building blocks out of which
  116. the Tcl event notifier is constructed.  The event notifier is the lowest
  117. layer in the Tcl event mechanism.  It consists of three things:
  118. .IP [1]
  119. Event sources: these represent the ways in which events can be
  120. generated.  For example, there is a timer event source that implements
  121. the fBTcl_CreateTimerHandlerfR procedure and the fBafterfR
  122. command, and there is a file event source that implements the
  123. fBTcl_CreateFileHandlerfR procedure on Unix systems.  An event
  124. source must work with the notifier to detect events at the right
  125. times, record them on the event queue, and eventually notify
  126. higher-level software that they have occurred.  The procedures
  127. fBTcl_CreateEventSourcefR, fBTcl_DeleteEventSourcefR,
  128. and fBTcl_SetMaxBlockTimefR, fBTcl_QueueEventfR, and
  129. fBTcl_DeleteEventsfR are used primarily by event sources.
  130. .IP [2]
  131. The event queue: for non-threaded applications,
  132. there is a single queue for the whole application,
  133. containing events that have been detected but not yet serviced.  Event
  134. sources place events onto the queue so that they may be processed in
  135. order at appropriate times during the event loop. The event queue
  136. guarantees a fair discipline of event handling, so that no event
  137. source can starve the others.  It also allows events to be saved for
  138. servicing at a future time.
  139. .VS 8.1
  140. Threaded applications work in a
  141. similar manner, except that there is a separate event queue for
  142. each thread containing a Tcl interpreter.
  143. fBTcl_QueueEventfR is used (primarily
  144. by event sources) to add events to the event queue and 
  145. fBTcl_DeleteEventsfR is used to remove events from the queue without
  146. processing them.  In a threaded application, fBTcl_QueueEventfR adds
  147. an event to the current thread's queue, and fBTcl_ThreadQueueEventfR
  148. adds an event to a queue in a specific thread.
  149. .IP [3]
  150. The event loop: in order to detect and process events, the application
  151. enters a loop that waits for events to occur, places them on the event
  152. queue, and then processes them.  Most applications will do this by
  153. calling the procedure fBTcl_DoOneEventfR, which is described in a
  154. separate manual entry.
  155. .PP
  156. Most Tcl applications need not worry about any of the internals of
  157. the Tcl notifier.  However, the notifier now has enough flexibility
  158. to be retargeted either for a new platform or to use an external event
  159. loop (such as the Motif event loop, when Tcl is embedded in a Motif
  160. application).  The procedures fBTcl_WaitForEventfR and
  161. fBTcl_SetTimerfR are normally implemented by Tcl, but may be
  162. replaced with new versions to retarget the notifier (the
  163. fBTcl_InitNotifierfR, fBTcl_AlertNotifierfR,
  164. fBTcl_FinalizeNotifierfR, fBTcl_SleepfR,
  165. fBTcl_CreateFileHandlerfR, and fBTcl_DeleteFileHandlerfR must
  166. also be replaced; see CREATING A NEW NOTIFIER below for details).
  167. The procedures fBTcl_ServiceAllfR, fBTcl_ServiceEventfR,
  168. fBTcl_GetServiceModefR, and fBTcl_SetServiceModefR are provided
  169. to help connect Tcl's event loop to an external event loop such as
  170. Motif's.
  171. .SH "NOTIFIER BASICS"
  172. .VE
  173. .PP
  174. The easiest way to understand how the notifier works is to consider
  175. what happens when fBTcl_DoOneEventfR is called.
  176. fBTcl_DoOneEventfR is passed a fIflagsfR argument that indicates
  177. what sort of events it is OK to process and also whether or not to
  178. block if no events are ready.  fBTcl_DoOneEventfR does the following
  179. things:
  180. .IP [1]
  181. Check the event queue to see if it contains any events that can
  182. be serviced.  If so, service the first possible event, remove it
  183. .VS 8.1
  184. from the queue, and return.  It does this by calling
  185. fBTcl_ServiceEventfR and passing in the fIflagsfR argument.
  186. .VE
  187. .IP [2]
  188. Prepare to block for an event.  To do this, fBTcl_DoOneEventfR
  189. invokes a fIsetup procedurefR in each event source.
  190. The event source will perform event-source specific initialization and
  191. .VS 8.1
  192. possibly call fBTcl_SetMaxBlockTimefR to limit how long
  193. .VE
  194. fBTcl_WaitForEventfR will block if no new events occur.
  195. .IP [3]
  196. Call fBTcl_WaitForEventfR.  This procedure is implemented differently
  197. on different platforms;  it waits for an event to occur, based on the
  198. information provided by the event sources.
  199. It may cause the application to block if fItimePtrfR specifies
  200. an interval other than 0.
  201. fBTcl_WaitForEventfR returns when something has happened,
  202. such as a file becoming readable or the interval given by fItimePtrfR
  203. expiring.  If there are no events for fBTcl_WaitForEventfR to
  204. wait for, so that it would block forever, then it returns immediately
  205. and fBTcl_DoOneEventfR returns 0.
  206. .IP [4]
  207. Call a fIcheck procedurefR in each event source.  The check
  208. procedure determines whether any events of interest to this source
  209. occurred.  If so, the events are added to the event queue.
  210. .IP [5]
  211. Check the event queue to see if it contains any events that can
  212. be serviced.  If so, service the first possible event, remove it
  213. from the queue, and return.
  214. .IP [6]
  215. See if there are idle callbacks pending. If so, invoke all of them and
  216. return.
  217. .IP [7]
  218. Either return 0 to indicate that no events were ready, or go back to
  219. step [2] if blocking was requested by the caller.
  220. .SH "CREATING A NEW EVENT SOURCE"
  221. .PP
  222. An event source consists of three procedures invoked by the notifier,
  223. plus additional C procedures that are invoked by higher-level code
  224. to arrange for event-driven callbacks.  The three procedures called
  225. by the notifier consist of the setup and check procedures described
  226. above, plus an additional procedure that is invoked when an event
  227. is removed from the event queue for servicing.
  228. .PP
  229. The procedure fBTcl_CreateEventSourcefR creates a new event source.
  230. Its arguments specify the setup procedure and check procedure for
  231. the event source.
  232. fISetupProcfR should match the following prototype:
  233. .CS
  234. typedef void Tcl_EventSetupProc(
  235. ClientData fIclientDatafR,
  236. int fIflagsfR);
  237. .CE
  238. The fIclientDatafR argument will be the same as the fIclientDatafR
  239. argument to fBTcl_CreateEventSourcefR;  it is typically used to
  240. point to private information managed by the event source.
  241. The fIflagsfR argument will be the same as the fIflagsfR
  242. argument passed to fBTcl_DoOneEventfR except that it will never
  243. be 0 (fBTcl_DoOneEventfR replaces 0 with fBTCL_ALL_EVENTSfR).
  244. fIFlagsfR indicates what kinds of events should be considered;
  245. if the bit corresponding to this event source isn't set, the event
  246. source should return immediately without doing anything.  For
  247. example, the file event source checks for the fBTCL_FILE_EVENTSfR
  248. bit.
  249. .PP
  250. fISetupProcfR's job is to make sure that the application wakes up
  251. when events of the desired type occur.  This is typically done in a
  252. platform-dependent fashion.  For example, under Unix an event source
  253. might call fBTcl_CreateFileHandlerfR; under Windows it might
  254. request notification with a Windows event.  For timer-driven event
  255. sources such as timer events or any polled event, the event source
  256. can call fBTcl_SetMaxBlockTimefR to force the application to wake
  257. up after a specified time even if no events have occurred.
  258. .VS 8.1
  259. If no event source calls fBTcl_SetMaxBlockTimefR
  260. then fBTcl_WaitForEventfR will wait as long as necessary for an
  261. event to occur; otherwise, it will only wait as long as the shortest
  262. interval passed to fBTcl_SetMaxBlockTimefR by one of the event
  263. sources.  If an event source knows that it already has events ready to
  264. report, it can request a zero maximum block time.  For example, the
  265. setup procedure for the X event source looks to see if there are
  266. events already queued.  If there are, it calls
  267. fBTcl_SetMaxBlockTimefR with a 0 block time so that
  268. fBTcl_WaitForEventfR does not block if there is no new data on the X
  269. connection.
  270. .VE
  271. The fItimePtrfR argument to fBTcl_WaitForEventfR points to
  272. a structure that describes a time interval in seconds and
  273. microseconds:
  274. .CS
  275. typedef struct Tcl_Time {
  276. long fIsecfR;
  277. long fIusecfR;
  278. } Tcl_Time;
  279. .CE
  280. The fIusecfR field should be less than 1000000.
  281. .PP
  282. .VS 8.1
  283. Information provided to fBTcl_SetMaxBlockTimefR
  284. is only used for the next call to fBTcl_WaitForEventfR; it is
  285. discarded after fBTcl_WaitForEventfR returns.
  286. .VE
  287. The next time an event wait is done each of the event sources'
  288. setup procedures will be called again, and they can specify new
  289. information for that event wait.
  290. .PP
  291. .VS 8.1
  292. If the application uses an external event loop rather than
  293. fBTcl_DoOneEventfR, the event sources may need to call
  294. fBTcl_SetMaxBlockTimefR at other times.  For example, if a new event
  295. handler is registered that needs to poll for events, the event source
  296. may call fBTcl_SetMaxBlockTimefR to set the block time to zero to
  297. force the external event loop to call Tcl.  In this case,
  298. fBTcl_SetMaxBlockTimefR invokes fBTcl_SetTimerfR with the shortest
  299. interval seen since the last call to fBTcl_DoOneEventfR or
  300. fBTcl_ServiceAllfR.
  301. .PP
  302. In addition to the generic procedure fBTcl_SetMaxBlockTimefR, other
  303. platform-specific procedures may also be available for
  304. fIsetupProcfR, if there is additional information needed by
  305. fBTcl_WaitForEventfR on that platform.  For example, on Unix systems
  306. the fBTcl_CreateFileHandlerfR interface can be used to wait for file events.
  307. .VE
  308. .PP
  309. The second procedure provided by each event source is its check
  310. procedure, indicated by the fIcheckProcfR argument to
  311. fBTcl_CreateEventSourcefR.  fICheckProcfR must match the
  312. following prototype:
  313. .CS
  314. typedef void Tcl_EventCheckProc(
  315. ClientData fIclientDatafR,
  316. int fIflagsfR);
  317. .CE
  318. The arguments to this procedure are the same as those for fIsetupProcfR.
  319. fBCheckProcfR is invoked by fBTcl_DoOneEventfR after it has waited
  320. for events.  Presumably at least one event source is now prepared to
  321. queue an event.  fBTcl_DoOneEventfR calls each of the event sources
  322. in turn, so they all have a chance to queue any events that are ready.
  323. The check procedure does two things.  First, it must see if any events
  324. have triggered.  Different event sources do this in different ways.
  325. .PP
  326. If an event source's check procedure detects an interesting event, it
  327. must add the event to Tcl's event queue.  To do this, the event source
  328. calls fBTcl_QueueEventfR.  The fIevPtrfR argument is a pointer to
  329. a dynamically allocated structure containing the event (see below for
  330. more information on memory management issues).  Each event source can
  331. define its own event structure with whatever information is relevant
  332. to that event source.  However, the first element of the structure
  333. must be a structure of type fBTcl_EventfR, and the address of this
  334. structure is used when communicating between the event source and the
  335. rest of the notifier.  A fBTcl_EventfR has the following definition:
  336. .CS
  337. typedef struct {
  338.     Tcl_EventProc *fIprocfR;
  339.     struct Tcl_Event *fInextPtrfR;
  340. } Tcl_Event;
  341. .CE
  342. The event source must fill in the fIprocfR field of
  343. the event before calling fBTcl_QueueEventfR.
  344. The fInextPtrfR is used to link together the events in the queue
  345. and should not be modified by the event source.
  346. .PP
  347. An event may be added to the queue at any of three positions, depending
  348. on the fIpositionfR argument to fBTcl_QueueEventfR:
  349. .IP fBTCL_QUEUE_TAILfR 24
  350. Add the event at the back of the queue, so that all other pending
  351. events will be serviced first.  This is almost always the right
  352. place for new events.
  353. .IP fBTCL_QUEUE_HEADfR 24
  354. Add the event at the front of the queue, so that it will be serviced
  355. before all other queued events.
  356. .IP fBTCL_QUEUE_MARKfR 24
  357. Add the event at the front of the queue, unless there are other
  358. events at the front whose position is fBTCL_QUEUE_MARKfR;  if so,
  359. add the new event just after all other fBTCL_QUEUE_MARKfR events.
  360. This value of fIpositionfR is used to insert an ordered sequence of
  361. events at the front of the queue, such as a series of
  362. Enter and Leave events synthesized during a grab or ungrab operation
  363. in Tk.
  364. .PP
  365. .VS 8.1
  366. When it is time to handle an event from the queue (steps 1 and 4
  367. above) fBTcl_ServiceEventfR will invoke the fIprocfR specified
  368. .VE
  369. in the first queued fBTcl_EventfR structure.
  370. fIProcfR must match the following prototype:
  371. .CS
  372. typedef int Tcl_EventProc(
  373. Tcl_Event *fIevPtrfR,
  374. int fIflagsfR);
  375. .CE
  376. The first argument to fIprocfR is a pointer to the event, which will
  377. be the same as the first argument to the fBTcl_QueueEventfR call that
  378. added the event to the queue.
  379. The second argument to fIprocfR is the fIflagsfR argument for the
  380. .VS 8.1
  381. current call to fBTcl_ServiceEventfR;  this is used by the event source
  382. .VE
  383. to return immediately if its events are not relevant.
  384. .PP
  385. It is up to fIprocfR to handle the event, typically by invoking
  386. one or more Tcl commands or C-level callbacks.
  387. Once the event source has finished handling the event it returns 1
  388. to indicate that the event can be removed from the queue.
  389. If for some reason the event source decides that the event cannot
  390. be handled at this time, it may return 0 to indicate that the event
  391. .VS 8.1
  392. should be deferred for processing later;  in this case fBTcl_ServiceEventfR
  393. .VE
  394. will go on to the next event in the queue and attempt to service it.
  395. There are several reasons why an event source might defer an event.
  396. One possibility is that events of this type are excluded by the
  397. fIflagsfR argument.
  398. For example, the file event source will always return 0 if the
  399. fBTCL_FILE_EVENTSfR bit isn't set in fIflagsfR.
  400. Another example of deferring events happens in Tk if
  401. fBTk_RestrictEventsfR has been invoked to defer certain kinds
  402. of window events.
  403. .PP
  404. .VS 8.1
  405. When fIprocfR returns 1, fBTcl_ServiceEventfR will remove the
  406. event from the event queue and free its storage.
  407. Note that the storage for an event must be allocated by
  408. the event source (using fBTcl_AllocfR or the Tcl macro fBckallocfR)
  409. before calling fBTcl_QueueEventfR, but it
  410. will be freed by fBTcl_ServiceEventfR, not by the event source.
  411. .PP
  412. Threaded applications work in a
  413. similar manner, except that there is a separate event queue for
  414. each thread containing a Tcl interpreter.
  415. Calling fBTcl_QueueEventfR in a multithreaded application adds
  416. an event to the current thread's queue.
  417. To add an event to another thread's queue, use fBTcl_ThreadQueueEventfR.
  418. fBTcl_ThreadQueueEventfR accepts as an argument a Tcl_ThreadId argument,
  419. which uniquely identifies a thread in a Tcl application.  To obtain the
  420. Tcl_ThreadID for the current thread, use the fBTcl_GetCurrentThreadfR
  421. procedure.  (A thread would then need to pass this identifier to other
  422. threads for those threads to be able to add events to its queue.)
  423. After adding an event to another thread's queue, you then typically
  424. need to call fBTcl_ThreadAlertfR to "wake up" that thread's notifier to
  425. alert it to the new event.
  426. .PP
  427. fBTcl_DeleteEventsfR can be used to explicitly remove one or more
  428. events from the event queue.  fBTcl_DeleteEventsfR calls fIprocfR
  429. for each event in the queue, deleting those for with the procedure
  430. returns 1.  Events for which the procedure returns 0 are left in the
  431. queue.  fIProcfR should match the following prototype:
  432. .CS
  433. typedef int Tcl_EventDeleteProc(
  434. Tcl_Event *fIevPtrfR,
  435. ClientData fIclientDatafR);
  436. .CE
  437. The fIclientDatafR argument will be the same as the fIclientDatafR
  438. argument to fBTcl_DeleteEventsfR; it is typically used to point to
  439. private information managed by the event source.  The fIevPtrfR will
  440. point to the next event in the queue.
  441. .PP
  442. fBTcl_DeleteEventSourcefR deletes an event source.  The fIsetupProcfR,
  443. fIcheckProcfR, and fIclientDatafR arguments must exactly match those
  444. provided to the fBTcl_CreateEventSourcefR for the event source to be deleted.
  445. If no such source exists, fBTcl_DeleteEventSourcefR has no effect.
  446. .VE
  447. .SH "CREATING A NEW NOTIFIER"
  448. .PP
  449. The notifier consists of all the procedures described in this manual
  450. entry, plus fBTcl_DoOneEventfR and fBTcl_SleepfR, which are
  451. .VS 8.1
  452. available on all platforms, and fBTcl_CreateFileHandlerfR and
  453. fBTcl_DeleteFileHandlerfR, which are Unix-specific.  Most of these
  454. procedures are generic, in that they are the same for all notifiers.
  455. However, eight of the procedures are notifier-dependent:
  456. fBTcl_InitNotifierfR, fBTcl_AlertNotifierfR, fBTcl_FinalizeNotifierfR, 
  457. fBTcl_SetTimerfR, fBTcl_SleepfR, fBTcl_WaitForEventfR,
  458. fBTcl_CreateFileHandlerfR and fBTcl_DeleteFileHandlerfR.  To
  459. support a new platform or to integrate Tcl with an
  460. application-specific event loop, you must write new versions of these
  461. procedures.
  462. .PP
  463. fBTcl_InitNotifierfR initializes the notifier state and returns
  464. a handle to the notifier state.  Tcl calls this
  465. procedure when initializing a Tcl interpreter.  Similarly,
  466. fBTcl_FinalizeNotifierfR shuts down the notifier, and is
  467. called by fBTcl_FinalizefR when shutting down a Tcl interpreter.
  468. .PP
  469. fBTcl_WaitForEventfR is the lowest-level procedure in the notifier;
  470. it is responsible for waiting for an ``interesting'' event to occur or
  471. for a given time to elapse.  Before fBTcl_WaitForEventfR is invoked,
  472. each of the event sources' setup procedure will have been invoked.
  473. The fItimePtrfR argument to
  474. fBTcl_WaitForEventfR gives the maximum time to block for an event,
  475. based on calls to fBTcl_SetMaxBlockTimefR made by setup procedures
  476. and on other information (such as the fBTCL_DONT_WAITfR bit in
  477. fIflagsfR).
  478. .PP
  479. Ideally, fBTcl_WaitForEventfR should only wait for an event
  480. to occur; it should not actually process the event in any way.
  481. Later on, the
  482. event sources will process the raw events and create Tcl_Events on
  483. the event queue in their fIcheckProcfR procedures.
  484. However, on some platforms (such as Windows) this isn't possible;
  485. events may be processed in fBTcl_WaitForEventfR, including queuing
  486. Tcl_Events and more (for example, callbacks for native widgets may be
  487. invoked).  The return value from fBTcl_WaitForEventfR must be either
  488. 0, 1, or -1.  On platforms such as Windows where events get processed in
  489. fBTcl_WaitForEventfR, a return value of 1 means that there may be more
  490. events still pending that haven't been processed.  This is a sign to the
  491. caller that it must call fBTcl_WaitForEventfR again if it wants all
  492. pending events to be processed. A 0 return value means that calling
  493. fBTcl_WaitForEventfR again will not have any effect: either this is a
  494. platform where fBTcl_WaitForEventfR only waits without doing any event
  495. processing, or fBTcl_WaitForEventfR knows for sure that there are no
  496. additional events to process (e.g. it returned because the time
  497. elapsed).  Finally, a return value of -1 means that the event loop is
  498. no longer operational and the application should probably unwind and
  499. terminate.  Under Windows this happens when a WM_QUIT message is received;
  500. under Unix it happens when fBTcl_WaitForEventfR would have waited
  501. forever because there were no active event sources and the timeout was
  502. infinite.
  503. .PP
  504. fBTcl_AlertNotifierfR is used in multithreaded applications to allow
  505. any thread to "wake up" the notifier to alert it to new events on its
  506. queue.  fBTcl_AlertNotifierfR requires as an argument the notifier
  507. handle returned by fBTcl_InitNotifierfR.
  508. .PP
  509. If the notifier will be used with an external event loop, then it must
  510. also support the fBTcl_SetTimerfR interface.  fBTcl_SetTimerfR is
  511. invoked by fBTcl_SetMaxBlockTimefR whenever the maximum blocking
  512. time has been reduced.  fBTcl_SetTimerfR should arrange for the
  513. external event loop to invoke fBTcl_ServiceAllfR after the specified
  514. interval even if no events have occurred.  This interface is needed
  515. because fBTcl_WaitForEventfR isn't invoked when there is an external
  516. event loop.  If the
  517. notifier will only be used from fBTcl_DoOneEventfR, then
  518. fBTcl_SetTimerfR need not do anything.
  519. .PP
  520. On Unix systems, the file event source also needs support from the
  521. notifier.  The file event source consists of the
  522. fBTcl_CreateFileHandlerfR and fBTcl_DeleteFileHandlerfR
  523. procedures, which are described in the fBTcl_CreateFileHandlerfR
  524. manual page.
  525. .PP
  526. The fBTcl_SleepfR and fBTcl_DoOneEventfR interfaces are described
  527. in their respective manual pages.
  528. .PP
  529. The easiest way to create a new notifier is to look at the code
  530. for an existing notifier, such as the files fBunix/tclUnixNotfy.cfR
  531. or fBwin/tclWinNotify.cfR in the Tcl source distribution.
  532. .SH "EXTERNAL EVENT LOOPS"
  533. .PP
  534. The notifier interfaces are designed so that Tcl can be embedded into
  535. applications that have their own private event loops.  In this case,
  536. the application does not call fBTcl_DoOneEventfR except in the case
  537. of recursive event loops such as calls to the Tcl commands fBupdatefR
  538. or fBvwaitfR.  Most of the time is spent in the external event loop
  539. of the application.  In this case the notifier must arrange for the
  540. external event loop to call back into Tcl when something
  541. happens on the various Tcl event sources.  These callbacks should
  542. arrange for appropriate Tcl events to be placed on the Tcl event queue.
  543. .PP
  544. Because the external event loop is not calling fBTcl_DoOneEventfR on
  545. a regular basis, it is up to the notifier to arrange for
  546. fBTcl_ServiceEventfR to be called whenever events are pending on the
  547. Tcl event queue.  The easiest way to do this is to invoke
  548. fBTcl_ServiceAllfR at the end of each callback from the external
  549. event loop.  This will ensure that all of the event sources are
  550. polled, any queued events are serviced, and any pending idle handlers
  551. are processed before returning control to the application.  In
  552. addition, event sources that need to poll for events can call
  553. fBTcl_SetMaxBlockTimefR to force the external event loop to call
  554. Tcl even if no events are available on the system event queue.
  555. .PP
  556. As a side effect of processing events detected in the main external
  557. event loop, Tcl may invoke fBTcl_DoOneEventfR to start a recursive event
  558. loop in commands like fBvwaitfR.  fBTcl_DoOneEventfR will invoke
  559. the external event loop, which will result in callbacks as described
  560. in the preceding paragraph, which will result in calls to
  561. fBTcl_ServiceAllfR.  However, in these cases it is undesirable to
  562. service events in fBTcl_ServiceAllfR.  Servicing events there is
  563. unnecessary because control will immediately return to the
  564. external event loop and hence to fBTcl_DoOneEventfR, which can
  565. service the events itself.  Furthermore, fBTcl_DoOneEventfR is
  566. supposed to service only a single event, whereas fBTcl_ServiceAllfR
  567. normally services all pending events.  To handle this situation,
  568. fBTcl_DoOneEventfR sets a flag for fBTcl_ServiceAllfR
  569. that causes it to return without servicing any events.
  570. This flag is called the fIservice modefR;
  571. fBTcl_DoOneEventfR restores it to its previous value before it returns.
  572. .PP
  573. In some cases, however, it may be necessary for fBTcl_ServiceAllfR
  574. to service events
  575. even when it has been invoked from fBTcl_DoOneEventfR.  This happens
  576. when there is yet another recursive event loop invoked via an
  577. event handler called by fBTcl_DoOneEventfR (such as one that is
  578. part of a native widget).  In this case, fBTcl_DoOneEventfR may not
  579. have a chance to service events so fBTcl_ServiceAllfR must service
  580. them all.  Any recursive event loop that calls an external event
  581. loop rather than fBTcl_DoOneEventfR must reset the service mode so
  582. that all events get processed in fBTcl_ServiceAllfR.  This is done
  583. by invoking the fBTcl_SetServiceModefR procedure.  If
  584. fBTcl_SetServiceModefR is passed fBTCL_SERVICE_NONEfR, then calls
  585. to fBTcl_ServiceAllfR will return immediately without processing any
  586. events.  If fBTcl_SetServiceModefR is passed fBTCL_SERVICE_ALLfR,
  587. then calls to fBTcl_ServiceAllfR will behave normally.
  588. fBTcl_SetServiceModefR returns the previous value of the service
  589. mode, which should be restored when the recursive loop exits.
  590. fBTcl_GetServiceModefR returns the current value of the service
  591. mode.
  592. .VE
  593. .SH "SEE ALSO"
  594. fBTcl_CreateFileHandlerfR, fBTcl_DeleteFileHandlerfR, fBTcl_SleepfR,
  595. fBTcl_DoOneEventfR, fBThread(3)fR
  596. .SH KEYWORDS
  597. event, notifier, event queue, event sources, file events, timer, idle, service mode, threads