Diff
Not logged in

Differences From Artifact [a196ba483c]:

To Artifact [739ee4fc67]:


1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19

20
21
22
23
24
25
26
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18

19
20
21
22
23
24
25
26












-
+





-
+







/*
 * tclUnixNotify.c --
 *
 *	This file contains the implementation of the select()-based
 *	Unix-specific notifier, which is the lowest-level part of the Tcl
 *	event loop. This file works together with generic/tclNotify.c.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclUnixNotfy.c,v 1.28 2005/07/24 22:56:44 dkf Exp $
 * RCS: @(#) $Id: tclUnixNotfy.c,v 1.29 2005/11/02 23:26:50 dkf Exp $
 */

#ifndef HAVE_COREFOUNDATION	/* Darwin/Mac OS X CoreFoundation notifier is
				 * in tclMacOSXNotify.c */
#include "tclInt.h"
#include <signal.h> 
#include <signal.h>

/*
 * This code does deep stub magic to allow replacement of the notifier at
 * runtime.
 */

extern TclStubs tclStubs;
205
206
207
208
209
210
211
212

213
214
215
216
217
218
219
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219







-
+







 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

ClientData
Tcl_InitNotifier()
Tcl_InitNotifier(void)
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

#ifdef TCL_THREADS
    tsdPtr->eventReady = 0;

    /*
257
258
259
260
261
262
263
264
265


266
267
268
269
270
271
272
257
258
259
260
261
262
263


264
265
266
267
268
269
270
271
272







-
-
+
+







 *	May terminate the background notifier thread if this is the last
 *	notifier instance.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_FinalizeNotifier(clientData)
    ClientData clientData;		/* Not used. */
Tcl_FinalizeNotifier(
    ClientData clientData)		/* Not used. */
{
#ifdef TCL_THREADS
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    Tcl_MutexLock(&notifierMutex);
    notifierCount--;

329
330
331
332
333
334
335
336
337


338
339
340
341
342
343
344
329
330
331
332
333
334
335


336
337
338
339
340
341
342
343
344







-
-
+
+







 * Side effects:
 *	Signals the notifier condition variable for the specified notifier.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_AlertNotifier(clientData)
    ClientData clientData;
Tcl_AlertNotifier(
    ClientData clientData)
{
#ifdef TCL_THREADS
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData;
    Tcl_MutexLock(&notifierMutex);
    tsdPtr->eventReady = 1;
    Tcl_ConditionNotify(&tsdPtr->waitCV);
    Tcl_MutexUnlock(&notifierMutex);
360
361
362
363
364
365
366
367
368


369
370
371
372
373
374
375
360
361
362
363
364
365
366


367
368
369
370
371
372
373
374
375







-
-
+
+







 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SetTimer(timePtr)
    Tcl_Time *timePtr;		/* Timeout value, may be NULL. */
Tcl_SetTimer(
    Tcl_Time *timePtr)		/* Timeout value, may be NULL. */
{
    /*
     * The interval timer doesn't do anything in this implementation, because
     * the only event loop is via Tcl_DoOneEvent, which passes timeout values
     * to Tcl_WaitForEvent.
     */

391
392
393
394
395
396
397
398
399


400
401
402
403
404
405
406
391
392
393
394
395
396
397


398
399
400
401
402
403
404
405
406







-
-
+
+







 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_ServiceModeHook(mode)
    int mode;			/* Either TCL_SERVICE_ALL, or
Tcl_ServiceModeHook(
    int mode)			/* Either TCL_SERVICE_ALL, or
				 * TCL_SERVICE_NONE. */
{
}

/*
 *----------------------------------------------------------------------
 *
414
415
416
417
418
419
420
421
422
423



424
425
426
427

428
429

430
431
432
433
434
435
436
414
415
416
417
418
419
420



421
422
423
424
425
426

427
428

429
430
431
432
433
434
435
436







-
-
-
+
+
+



-
+

-
+







 * Side effects:
 *	Creates a new file handler structure.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_CreateFileHandler(fd, mask, proc, clientData)
    int fd;			/* Handle of stream to watch. */
    int mask;			/* OR'ed combination of TCL_READABLE,
Tcl_CreateFileHandler(
    int fd,			/* Handle of stream to watch. */
    int mask,			/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, and TCL_EXCEPTION: indicates
				 * conditions under which proc should be
				 * called. */
    Tcl_FileProc *proc;		/* Function to call for each selected
    Tcl_FileProc *proc,		/* Function to call for each selected
				 * event. */
    ClientData clientData;	/* Arbitrary data to pass to proc. */
    ClientData clientData)	/* Arbitrary data to pass to proc. */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    FileHandler *filePtr;

    if (tclStubs.tcl_CreateFileHandler != tclOriginalNotifier.createFileHandlerProc) {
	tclStubs.tcl_CreateFileHandler(fd, mask, proc, clientData);
	return;
490
491
492
493
494
495
496
497
498


499
500
501
502
503
504
505
490
491
492
493
494
495
496


497
498
499
500
501
502
503
504
505







-
-
+
+







 * Side effects:
 *	If a callback was previously registered on file, remove it.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_DeleteFileHandler(fd)
    int fd;			/* Stream id for which to remove callback
Tcl_DeleteFileHandler(
    int fd)			/* Stream id for which to remove callback
				 * function. */
{
    FileHandler *filePtr, *prevPtr;
    int i;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (tclStubs.tcl_DeleteFileHandler != tclOriginalNotifier.deleteFileHandlerProc) {
582
583
584
585
586
587
588
589
590
591



592
593
594
595
596
597
598
582
583
584
585
586
587
588



589
590
591
592
593
594
595
596
597
598







-
-
-
+
+
+







 * Side effects:
 *	Whatever the file handler's callback function does.
 *
 *----------------------------------------------------------------------
 */

static int
FileHandlerEventProc(evPtr, flags)
    Tcl_Event *evPtr;		/* Event to service. */
    int flags;			/* Flags that indicate what events to handle,
FileHandlerEventProc(
    Tcl_Event *evPtr,		/* Event to service. */
    int flags)			/* Flags that indicate what events to handle,
				 * such as TCL_FILE_EVENTS. */
{
    int mask;
    FileHandler *filePtr;
    FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) evPtr;
    ThreadSpecificData *tsdPtr;

651
652
653
654
655
656
657
658
659


660
661
662
663
664
665
666
651
652
653
654
655
656
657


658
659
660
661
662
663
664
665
666







-
-
+
+







 * Side effects:
 *	Queues file events that are detected by the select.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_WaitForEvent(timePtr)
    Tcl_Time *timePtr;		/* Maximum block time, or NULL. */
Tcl_WaitForEvent(
    Tcl_Time *timePtr)		/* Maximum block time, or NULL. */
{
    FileHandler *filePtr;
    FileHandlerEvent *fileEvPtr;
    int mask;
    Tcl_Time myTime;
#ifdef TCL_THREADS
    int waitForFiles;
882
883
884
885
886
887
888
889
890


891
892
893
894
895
896
897
882
883
884
885
886
887
888


889
890
891
892
893
894
895
896
897







-
-
+
+







 *	The trigger pipe used to signal the notifier thread is created when
 *	the notifier thread first starts.
 *
 *----------------------------------------------------------------------
 */

static void
NotifierThreadProc(clientData)
    ClientData clientData;	/* Not used. */
NotifierThreadProc(
    ClientData clientData)	/* Not used. */
{
    ThreadSpecificData *tsdPtr;
    fd_set readableMask;
    fd_set writableMask;
    fd_set exceptionalMask;
    int fds[2];
    int i, status, numFdBits = 0, receivePipe;