~ubuntu-branches/ubuntu/natty/perl-tk/natty

« back to all changes in this revision

Viewing changes to debian/patches/selectmaskon64bit.dpatch

  • Committer: Bazaar Package Importer
  • Author(s): Colin Tuckley
  • Date: 2010-04-10 12:01:27 UTC
  • Revision ID: james.westby@ubuntu.com-20100410120127-gvo4d0zwh1y3lzdk
Tags: 1:804.028-7
* Fix the manpage for Tk::TixGrid (Closes: #557106).
* Bump standards version to 3.8.4 (no changes required).
* Fix broken select mask on 64 bit architectures
  using upstream patch (Closes: #574884).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /bin/sh /usr/share/dpatch/dpatch-run
 
2
## selectmaskon64bit.dpatch by  <colint@debian.org>
 
3
##
 
4
## All lines beginning with `## DP:' are a description of the patch.
 
5
## DP: Backported fix for bug 574884. Upstream ticket 32034
 
6
 
 
7
@DPATCH@
 
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
 
11
@@ -1961,6 +1961,7 @@
 
12
 t/exefiles.t
 
13
 t/fbox.t
 
14
 t/fileevent.t
 
15
+t/fileevent2.t
 
16
 t/fileselect.t
 
17
 t/font.t
 
18
 t/fork.t
 
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
 
22
@@ -69,6 +69,18 @@
 
23
 } FileHandlerEvent;
 
24
 
 
25
 /*
 
26
+ *
 
27
+ * The following structure contains a set of select() masks to track
 
28
+ * readable, writable, and exceptional conditions.
 
29
+ */
 
30
+
 
31
+typedef struct SelectMasks {
 
32
+    fd_set readable;
 
33
+    fd_set writable;
 
34
+    fd_set exceptional;
 
35
+} SelectMasks;
 
36
+
 
37
+/*
 
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.
 
41
@@ -77,13 +89,12 @@
 
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
 
47
+    
 
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
 
58
@@ -425,7 +436,6 @@
 
59
 {
 
60
     ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
 
61
     FileHandler *filePtr;
 
62
-    int index, bit;
 
63
 
 
64
     if (tclStubs.tcl_CreateFileHandler != tclOriginalNotifier.createFileHandlerProc) {
 
65
        tclStubs.tcl_CreateFileHandler(fd, mask, proc, clientData);
 
66
@@ -453,22 +463,20 @@
 
67
      * Update the check masks for this file.
 
68
      */
 
69
 
 
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) );
 
76
     } else {
 
77
-       tsdPtr->checkMasks[index] &= ~bit;
 
78
+       FD_CLR( fd, &(tsdPtr->checkMasks.readable) );
 
79
     }
 
80
-    if (mask & TCL_WRITABLE) {
 
81
-       (tsdPtr->checkMasks+MASK_SIZE)[index] |= bit;
 
82
+    if ( mask & TCL_WRITABLE ) {
 
83
+       FD_SET( fd, &(tsdPtr->checkMasks.writable) );
 
84
     } else {
 
85
-       (tsdPtr->checkMasks+MASK_SIZE)[index] &= ~bit;
 
86
+       FD_CLR( fd, &(tsdPtr->checkMasks.writable) );
 
87
     }
 
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) );
 
92
     } else {
 
93
-       (tsdPtr->checkMasks+2*(MASK_SIZE))[index] &= ~bit;
 
94
+       FD_CLR( fd, &(tsdPtr->checkMasks.exceptional) );
 
95
     }
 
96
     if (tsdPtr->numFdBits <= fd) {
 
97
        tsdPtr->numFdBits = fd+1;
 
98
@@ -497,8 +505,7 @@
 
99
     int fd;             /* Stream id for which to remove callback procedure. */
 
100
 {
 
101
     FileHandler *filePtr, *prevPtr;
 
102
-    int index, bit, i;
 
103
-    unsigned long flags;
 
104
+    int i;
 
105
     ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
 
106
 
 
107
     if (tclStubs.tcl_DeleteFileHandler != tclOriginalNotifier.deleteFileHandlerProc) {
 
108
@@ -524,17 +531,14 @@
 
109
      * Update the check masks for this file.
 
110
      */
 
111
 
 
112
-    index = fd/(NBBY*sizeof(fd_mask));
 
113
-    bit = 1 << (fd%(NBBY*sizeof(fd_mask)));
 
114
-
 
115
     if (filePtr->mask & TCL_READABLE) {
 
116
-       tsdPtr->checkMasks[index] &= ~bit;
 
117
+       FD_CLR( fd, &(tsdPtr->checkMasks.readable) );
 
118
     }
 
119
     if (filePtr->mask & TCL_WRITABLE) {
 
120
-       (tsdPtr->checkMasks+MASK_SIZE)[index] &= ~bit;
 
121
+       FD_CLR( fd, &(tsdPtr->checkMasks.writable) );
 
122
     }
 
123
     if (filePtr->mask & TCL_EXCEPTION) {
 
124
-       (tsdPtr->checkMasks+2*(MASK_SIZE))[index] &= ~bit;
 
125
+       FD_CLR( fd, &(tsdPtr->checkMasks.exceptional) );
 
126
     }
 
127
 
 
128
     /*
 
129
@@ -542,17 +546,12 @@
 
130
      */
 
131
 
 
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];
 
137
-           if (flags) {
 
138
-               for (i = (NBBY*sizeof(fd_mask)); i > 0; i--) {
 
139
-                   if (flags & (((unsigned long)1) << (i-1))) {
 
140
-                       break;
 
141
-                   }
 
142
-               }
 
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;
 
150
                break;
 
151
            }
 
152
        }
 
153
@@ -674,7 +673,7 @@
 
154
     FileHandler *filePtr;
 
155
     FileHandlerEvent *fileEvPtr;
 
156
     struct timeval timeout, *timeoutPtr;
 
157
-    int bit, index, mask;
 
158
+    int mask;
 
159
 #ifdef TCL_THREADS
 
160
     int waitForFiles;
 
161
 #else
 
162
@@ -756,7 +755,9 @@
 
163
        write(triggerPipe, "", 1);
 
164
     }
 
165
 
 
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) );
 
170
 
 
171
     if (!tsdPtr->eventReady) {
 
172
        Tcl_ConditionWait(&tsdPtr->waitCV, &notifierMutex, timePtr);
 
173
@@ -786,12 +787,12 @@
 
174
 
 
175
 
 
176
 #else
 
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),
 
188
+                      timeoutPtr );
 
189
 
 
190
     /*
 
191
      * Some systems don't clear the masks after an error, so
 
192
@@ -799,7 +800,9 @@
 
193
      */
 
194
 
 
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 ) );
 
200
     }
 
201
 
 
202
 #ifdef _LANG
 
203
@@ -819,17 +822,15 @@
 
204
 
 
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)));
 
209
-       mask = 0;
 
210
 
 
211
-       if (tsdPtr->readyMasks[index] & bit) {
 
212
+       mask = 0;
 
213
+       if ( FD_ISSET( filePtr->fd, &(tsdPtr->readyMasks.readable) ) ) {
 
214
            mask |= TCL_READABLE;
 
215
        }
 
216
-       if ((tsdPtr->readyMasks+MASK_SIZE)[index] & bit) {
 
217
+       if ( FD_ISSET( filePtr->fd, &(tsdPtr->readyMasks.writable) ) ) {
 
218
            mask |= TCL_WRITABLE;
 
219
        }
 
220
-       if ((tsdPtr->readyMasks+2*(MASK_SIZE))[index] & bit) {
 
221
+       if ( FD_ISSET( filePtr->fd, &(tsdPtr->readyMasks.exceptional) ) ) {
 
222
            mask |= TCL_EXCEPTION;
 
223
        }
 
224
 
 
225
@@ -888,13 +889,13 @@
 
226
     ClientData clientData;      /* Not used. */
 
227
 {
 
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;
 
234
     int fds[2];
 
235
-    int i, status, index, bit, numFdBits, receivePipe;
 
236
-    long found, word;
 
237
+    int i, status, numFdBits, receivePipe;
 
238
+    long found;
 
239
     struct timeval poll = {0., 0.}, *timePtr;
 
240
-    int maskSize = 3 * ((MASK_SIZE) / sizeof(long)) * sizeof(fd_mask);
 
241
     char buf[2];
 
242
 
 
243
     if (pipe(fds) != 0) {
 
244
@@ -942,27 +943,31 @@
 
245
      */
 
246
 
 
247
     while (1) {
 
248
-       /*
 
249
-        * Set up the select mask to include the receive pipe.
 
250
-        */
 
251
 
 
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 );
 
260
 
 
261
        /*
 
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.
 
265
         */
 
266
 
 
267
        Tcl_MutexLock(&notifierMutex);
 
268
        timePtr = NULL;
 
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 );
 
276
+               }
 
277
+               if ( FD_ISSET( i, &(tsdPtr->checkMasks.writable) ) ) {
 
278
+                   FD_SET( i, &writableMask );
 
279
+               }
 
280
+               if ( FD_ISSET( i, &(tsdPtr->checkMasks.exceptional) ) ) {
 
281
+                   FD_SET( i, &exceptionalMask );
 
282
+               }
 
283
            }
 
284
-           if (tsdPtr->numFdBits > numFdBits) {
 
285
+           if ( tsdPtr->numFdBits > numFdBits ) {
 
286
                numFdBits = tsdPtr->numFdBits;
 
287
            }
 
288
            if (tsdPtr->pollState & POLL_WANT) {
 
289
@@ -977,11 +982,17 @@
 
290
        }
 
291
        Tcl_MutexUnlock(&notifierMutex);
 
292
 
 
293
-       maskSize = 3 * ((MASK_SIZE) / sizeof(long)) * sizeof(fd_mask);
 
294
+       /*
 
295
+        * Set up the select mask to include the receive pipe.
 
296
+        */
 
297
 
 
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;
 
303
+       }
 
304
+       FD_SET( receivePipe, &readableMask );
 
305
+
 
306
+       if ( select( numFdBits, &readableMask, &writableMask,
 
307
+                    &exceptionalMask, timePtr) == -1 ) {
 
308
            /*
 
309
             * Try again immediately on an error.
 
310
             */
 
311
@@ -997,11 +1008,24 @@
 
312
        for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
 
313
            found = 0;
 
314
 
 
315
-           for (i = 0; i < maskSize; i++) {
 
316
-               word = maskPtr[i] & ((long*)tsdPtr->checkMasks)[i];
 
317
-               found |= word;
 
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) );
 
323
+                   found = 1;
 
324
+               }
 
325
+               if ( FD_ISSET( i, &(tsdPtr->checkMasks.writable) )
 
326
+                    && FD_ISSET( i, &writableMask ) ) {
 
327
+                   FD_SET( i, &(tsdPtr->readyMasks.writable) );
 
328
+                   found = 1;
 
329
+               }
 
330
+               if ( FD_ISSET( i, &(tsdPtr->checkMasks.exceptional) )
 
331
+                    && FD_ISSET( i, &exceptionalMask ) ) {
 
332
+                   FD_SET( i, &(tsdPtr->readyMasks.exceptional) );
 
333
+                   found = 1;
 
334
+               }
 
335
            }
 
336
+                              
 
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.
 
342
         */
 
343
 
 
344
-       if (masks[index] & bit) {
 
345
+       if ( FD_ISSET( receivePipe, &readableMask ) ) {
 
346
            i = read(receivePipe, buf, 1);
 
347
 
 
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
 
352
@@ -0,0 +1,49 @@
 
353
+#!/usr/bin/perl -w
 
354
+# -*- perl -*-
 
355
+
 
356
+#
 
357
+# $Id: $
 
358
+# Author: Slaven Rezic
 
359
+#
 
360
+
 
361
+use strict;
 
362
+
 
363
+use Tk;
 
364
+
 
365
+BEGIN {
 
366
+    if (!eval q{
 
367
+       use 5.006; # three-arg open
 
368
+       use Test::More;
 
369
+       1;
 
370
+    }) {
 
371
+       print "1..0 # skip: no Test::More module\n";
 
372
+       exit;
 
373
+    }
 
374
+}
 
375
+
 
376
+plan tests => 1;
 
377
+
 
378
+my @fh;
 
379
+my $callback_called = 0;
 
380
+
 
381
+my $mw = tkinit;
 
382
+$mw->geometry("+10+10");
 
383
+$mw->idletasks;
 
384
+
 
385
+# A variant of the problem reported in
 
386
+# http://rt.cpan.org/Ticket/Display.html?id=32034
 
387
+#
 
388
+# tclUnixNotify.c used to do bit-handling for the select() mask
 
389
+# itself, but this was broken for 64bit machines.
 
390
+for (1..100) {
 
391
+    open my $dup, "<&", \*STDIN or die "Can't dup STDIN: $!";
 
392
+    push @fh, $dup;
 
393
+    $mw->fileevent($dup, "readable", sub { $callback_called++ });
 
394
+}
 
395
+
 
396
+$mw->after(300, sub { $mw->destroy });
 
397
+MainLoop;
 
398
+
 
399
+ok($callback_called == 0, "Fileevent callback should never be called");
 
400
+
 
401
+__END__