1
#! /bin/sh /usr/share/dpatch/dpatch-run
2
## selectmaskon64bit.dpatch by <colint@debian.org>
4
## All lines beginning with `## DP:' are a description of the patch.
5
## DP: Backported fix for bug 574884. Upstream ticket 32034
8
diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' perl-tk-804.028~/MANIFEST perl-tk-804.028/MANIFEST
9
--- perl-tk-804.028~/MANIFEST 2007-11-15 20:56:56.000000000 +0000
10
+++ perl-tk-804.028/MANIFEST 2010-04-10 11:42:34.000000000 +0100
19
diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' perl-tk-804.028~/pTk/mTk/tclUnix/tclUnixNotfy.c perl-tk-804.028/pTk/mTk/tclUnix/tclUnixNotfy.c
20
--- perl-tk-804.028~/pTk/mTk/tclUnix/tclUnixNotfy.c 2007-05-05 19:39:37.000000000 +0100
21
+++ perl-tk-804.028/pTk/mTk/tclUnix/tclUnixNotfy.c 2010-04-10 11:50:49.000000000 +0100
27
+ * The following structure contains a set of select() masks to track
28
+ * readable, writable, and exceptional conditions.
31
+typedef struct SelectMasks {
38
* The following static structure contains the state information for the
39
* select based implementation of the Tcl notifier. One of these structures
40
* is created for each thread that is using the notifier.
42
typedef struct ThreadSpecificData {
43
FileHandler *firstFileHandlerPtr;
44
/* Pointer to head of file handler list. */
45
- fd_mask checkMasks[3*MASK_SIZE];
46
- /* This array is used to build up the masks
48
+ SelectMasks checkMasks; /* This structure is used to build up the masks
49
* to be used in the next call to select.
50
* Bits are set in response to calls to
51
* Tcl_CreateFileHandler. */
52
- fd_mask readyMasks[3*MASK_SIZE];
53
- /* This array reflects the readable/writable
54
+ SelectMasks readyMasks; /* This array reflects the readable/writable
55
* conditions that were found to exist by the
56
* last call to select. */
57
int numFdBits; /* Number of valid bits in checkMasks
60
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
64
if (tclStubs.tcl_CreateFileHandler != tclOriginalNotifier.createFileHandlerProc) {
65
tclStubs.tcl_CreateFileHandler(fd, mask, proc, clientData);
67
* Update the check masks for this file.
70
- index = fd/(NBBY*sizeof(fd_mask));
71
- bit = 1 << (fd%(NBBY*sizeof(fd_mask)));
72
- if (mask & TCL_READABLE) {
73
- tsdPtr->checkMasks[index] |= bit;
74
+ if ( mask & TCL_READABLE ) {
75
+ FD_SET( fd, &(tsdPtr->checkMasks.readable) );
77
- tsdPtr->checkMasks[index] &= ~bit;
78
+ FD_CLR( fd, &(tsdPtr->checkMasks.readable) );
80
- if (mask & TCL_WRITABLE) {
81
- (tsdPtr->checkMasks+MASK_SIZE)[index] |= bit;
82
+ if ( mask & TCL_WRITABLE ) {
83
+ FD_SET( fd, &(tsdPtr->checkMasks.writable) );
85
- (tsdPtr->checkMasks+MASK_SIZE)[index] &= ~bit;
86
+ FD_CLR( fd, &(tsdPtr->checkMasks.writable) );
88
- if (mask & TCL_EXCEPTION) {
89
- (tsdPtr->checkMasks+2*(MASK_SIZE))[index] |= bit;
90
+ if ( mask & TCL_EXCEPTION ) {
91
+ FD_SET( fd, &(tsdPtr->checkMasks.exceptional) );
93
- (tsdPtr->checkMasks+2*(MASK_SIZE))[index] &= ~bit;
94
+ FD_CLR( fd, &(tsdPtr->checkMasks.exceptional) );
96
if (tsdPtr->numFdBits <= fd) {
97
tsdPtr->numFdBits = fd+1;
99
int fd; /* Stream id for which to remove callback procedure. */
101
FileHandler *filePtr, *prevPtr;
103
- unsigned long flags;
105
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
107
if (tclStubs.tcl_DeleteFileHandler != tclOriginalNotifier.deleteFileHandlerProc) {
108
@@ -524,17 +531,14 @@
109
* Update the check masks for this file.
112
- index = fd/(NBBY*sizeof(fd_mask));
113
- bit = 1 << (fd%(NBBY*sizeof(fd_mask)));
115
if (filePtr->mask & TCL_READABLE) {
116
- tsdPtr->checkMasks[index] &= ~bit;
117
+ FD_CLR( fd, &(tsdPtr->checkMasks.readable) );
119
if (filePtr->mask & TCL_WRITABLE) {
120
- (tsdPtr->checkMasks+MASK_SIZE)[index] &= ~bit;
121
+ FD_CLR( fd, &(tsdPtr->checkMasks.writable) );
123
if (filePtr->mask & TCL_EXCEPTION) {
124
- (tsdPtr->checkMasks+2*(MASK_SIZE))[index] &= ~bit;
125
+ FD_CLR( fd, &(tsdPtr->checkMasks.exceptional) );
129
@@ -542,17 +546,12 @@
132
if (fd+1 == tsdPtr->numFdBits) {
133
- for (tsdPtr->numFdBits = 0; index >= 0; index--) {
134
- flags = tsdPtr->checkMasks[index]
135
- | (tsdPtr->checkMasks+MASK_SIZE)[index]
136
- | (tsdPtr->checkMasks+2*(MASK_SIZE))[index];
138
- for (i = (NBBY*sizeof(fd_mask)); i > 0; i--) {
139
- if (flags & (((unsigned long)1) << (i-1))) {
143
- tsdPtr->numFdBits = index * (NBBY*sizeof(fd_mask)) + i;
144
+ tsdPtr->numFdBits = 0;
145
+ for (i = fd-1; i >= 0; i--) {
146
+ if ( FD_ISSET( i, &(tsdPtr->checkMasks.readable) )
147
+ || FD_ISSET( i, &(tsdPtr->checkMasks.writable) )
148
+ || FD_ISSET( i, &(tsdPtr->checkMasks.exceptional ) ) ) {
149
+ tsdPtr->numFdBits = i+1;
154
FileHandler *filePtr;
155
FileHandlerEvent *fileEvPtr;
156
struct timeval timeout, *timeoutPtr;
157
- int bit, index, mask;
163
write(triggerPipe, "", 1);
166
- memset((VOID *) tsdPtr->readyMasks, 0, 3*MASK_SIZE*sizeof(fd_mask));
167
+ FD_ZERO( &(tsdPtr->readyMasks.readable) );
168
+ FD_ZERO( &(tsdPtr->readyMasks.writable) );
169
+ FD_ZERO( &(tsdPtr->readyMasks.exceptional) );
171
if (!tsdPtr->eventReady) {
172
Tcl_ConditionWait(&tsdPtr->waitCV, ¬ifierMutex, timePtr);
173
@@ -786,12 +787,12 @@
177
- memcpy((VOID *) tsdPtr->readyMasks, (VOID *) tsdPtr->checkMasks,
178
- 3*MASK_SIZE*sizeof(fd_mask));
179
- numFound = select(tsdPtr->numFdBits,
180
- (SELECT_MASK *) &tsdPtr->readyMasks[0],
181
- (SELECT_MASK *) &tsdPtr->readyMasks[MASK_SIZE],
182
- (SELECT_MASK *) &tsdPtr->readyMasks[2*MASK_SIZE], timeoutPtr);
183
+ tsdPtr->readyMasks = tsdPtr->checkMasks;
184
+ numFound = select( tsdPtr->numFdBits,
185
+ &(tsdPtr->readyMasks.readable),
186
+ &(tsdPtr->readyMasks.writable),
187
+ &(tsdPtr->readyMasks.exceptional),
191
* Some systems don't clear the masks after an error, so
195
if (numFound == -1) {
196
- memset((VOID *) tsdPtr->readyMasks, 0, 3*MASK_SIZE*sizeof(fd_mask));
197
+ FD_ZERO( &(tsdPtr->readyMasks.readable ) );
198
+ FD_ZERO( &(tsdPtr->readyMasks.writable ) );
199
+ FD_ZERO( &(tsdPtr->readyMasks.exceptional ) );
203
@@ -819,17 +822,15 @@
205
for (filePtr = tsdPtr->firstFileHandlerPtr; (filePtr != NULL);
206
filePtr = filePtr->nextPtr) {
207
- index = filePtr->fd / (NBBY*sizeof(fd_mask));
208
- bit = 1 << (filePtr->fd % (NBBY*sizeof(fd_mask)));
211
- if (tsdPtr->readyMasks[index] & bit) {
213
+ if ( FD_ISSET( filePtr->fd, &(tsdPtr->readyMasks.readable) ) ) {
214
mask |= TCL_READABLE;
216
- if ((tsdPtr->readyMasks+MASK_SIZE)[index] & bit) {
217
+ if ( FD_ISSET( filePtr->fd, &(tsdPtr->readyMasks.writable) ) ) {
218
mask |= TCL_WRITABLE;
220
- if ((tsdPtr->readyMasks+2*(MASK_SIZE))[index] & bit) {
221
+ if ( FD_ISSET( filePtr->fd, &(tsdPtr->readyMasks.exceptional) ) ) {
222
mask |= TCL_EXCEPTION;
225
@@ -888,13 +889,13 @@
226
ClientData clientData; /* Not used. */
228
ThreadSpecificData *tsdPtr;
229
- fd_mask masks[3*MASK_SIZE];
230
- long *maskPtr = (long *)masks; /* masks[] cast to type long[] */
231
+ fd_set readableMask;
232
+ fd_set writableMask;
233
+ fd_set exceptionalMask;
235
- int i, status, index, bit, numFdBits, receivePipe;
237
+ int i, status, numFdBits, receivePipe;
239
struct timeval poll = {0., 0.}, *timePtr;
240
- int maskSize = 3 * ((MASK_SIZE) / sizeof(long)) * sizeof(fd_mask);
243
if (pipe(fds) != 0) {
244
@@ -942,27 +943,31 @@
249
- * Set up the select mask to include the receive pipe.
252
- memset((VOID *)masks, 0, 3*MASK_SIZE*sizeof(fd_mask));
253
- numFdBits = receivePipe + 1;
254
- index = receivePipe / (NBBY*sizeof(fd_mask));
255
- bit = 1 << (receivePipe % (NBBY*sizeof(fd_mask)));
256
- masks[index] |= bit;
257
+ FD_ZERO( &readableMask );
258
+ FD_ZERO( &writableMask );
259
+ FD_ZERO( &exceptionalMask );
262
- * Add in the check masks from all of the waiting notifiers.
263
+ * Compute the logical OR of the select masks from all the
264
+ * waiting notifiers.
267
Tcl_MutexLock(¬ifierMutex);
269
- for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
270
- for (i = 0; i < maskSize; i++) {
271
- maskPtr[i] |= ((long*)tsdPtr->checkMasks)[i];
272
+ for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
273
+ for ( i = tsdPtr->numFdBits-1; i >= 0; --i ) {
274
+ if ( FD_ISSET( i, &(tsdPtr->checkMasks.readable) ) ) {
275
+ FD_SET( i, &readableMask );
277
+ if ( FD_ISSET( i, &(tsdPtr->checkMasks.writable) ) ) {
278
+ FD_SET( i, &writableMask );
280
+ if ( FD_ISSET( i, &(tsdPtr->checkMasks.exceptional) ) ) {
281
+ FD_SET( i, &exceptionalMask );
284
- if (tsdPtr->numFdBits > numFdBits) {
285
+ if ( tsdPtr->numFdBits > numFdBits ) {
286
numFdBits = tsdPtr->numFdBits;
288
if (tsdPtr->pollState & POLL_WANT) {
289
@@ -977,11 +982,17 @@
291
Tcl_MutexUnlock(¬ifierMutex);
293
- maskSize = 3 * ((MASK_SIZE) / sizeof(long)) * sizeof(fd_mask);
295
+ * Set up the select mask to include the receive pipe.
298
- if (select(numFdBits, (SELECT_MASK *) &masks[0],
299
- (SELECT_MASK *) &masks[MASK_SIZE],
300
- (SELECT_MASK *) &masks[2*MASK_SIZE], timePtr) == -1) {
301
+ if ( receivePipe >= numFdBits ) {
302
+ numFdBits = receivePipe + 1;
304
+ FD_SET( receivePipe, &readableMask );
306
+ if ( select( numFdBits, &readableMask, &writableMask,
307
+ &exceptionalMask, timePtr) == -1 ) {
309
* Try again immediately on an error.
311
@@ -997,11 +1008,24 @@
312
for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
315
- for (i = 0; i < maskSize; i++) {
316
- word = maskPtr[i] & ((long*)tsdPtr->checkMasks)[i];
318
- (((long*)(tsdPtr->readyMasks))[i]) = word;
319
+ for ( i = tsdPtr->numFdBits-1; i >= 0; --i ) {
320
+ if ( FD_ISSET( i, &(tsdPtr->checkMasks.readable) )
321
+ && FD_ISSET( i, &readableMask ) ) {
322
+ FD_SET( i, &(tsdPtr->readyMasks.readable) );
325
+ if ( FD_ISSET( i, &(tsdPtr->checkMasks.writable) )
326
+ && FD_ISSET( i, &writableMask ) ) {
327
+ FD_SET( i, &(tsdPtr->readyMasks.writable) );
330
+ if ( FD_ISSET( i, &(tsdPtr->checkMasks.exceptional) )
331
+ && FD_ISSET( i, &exceptionalMask ) ) {
332
+ FD_SET( i, &(tsdPtr->readyMasks.exceptional) );
337
if (found || (tsdPtr->pollState & POLL_DONE)) {
338
tsdPtr->eventReady = 1;
339
if (tsdPtr->onList) {
340
@@ -1035,7 +1059,7 @@
341
* to avoid a race condition we only read one at a time.
344
- if (masks[index] & bit) {
345
+ if ( FD_ISSET( receivePipe, &readableMask ) ) {
346
i = read(receivePipe, buf, 1);
348
if ((i == 0) || ((i == 1) && (buf[0] == 'q'))) {
349
diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' perl-tk-804.028~/t/fileevent2.t perl-tk-804.028/t/fileevent2.t
350
--- perl-tk-804.028~/t/fileevent2.t 1970-01-01 01:00:00.000000000 +0100
351
+++ perl-tk-804.028/t/fileevent2.t 2010-04-10 11:42:34.000000000 +0100
358
+# Author: Slaven Rezic
367
+ use 5.006; # three-arg open
371
+ print "1..0 # skip: no Test::More module\n";
379
+my $callback_called = 0;
382
+$mw->geometry("+10+10");
385
+# A variant of the problem reported in
386
+# http://rt.cpan.org/Ticket/Display.html?id=32034
388
+# tclUnixNotify.c used to do bit-handling for the select() mask
389
+# itself, but this was broken for 64bit machines.
391
+ open my $dup, "<&", \*STDIN or die "Can't dup STDIN: $!";
393
+ $mw->fileevent($dup, "readable", sub { $callback_called++ });
396
+$mw->after(300, sub { $mw->destroy });
399
+ok($callback_called == 0, "Fileevent callback should never be called");