summaryrefslogtreecommitdiff
path: root/debian/patches/19flowcontrol_lockup.dpatch
blob: dca2b0867e87d0643c495e155f15074323eacdbb (plain)
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#! /bin/sh /usr/share/dpatch/dpatch-run
## 19flowcontrol_lockup.dpatch by  <hesso@pool.math.tu-berlin.de>
##
## DP: Make Flush() truly non-blocking by employing an extra select().
## DP: Thus D_userfd is assured to be in non-blocking mode on return
## DP: (even if the return was premature due to select() timing out),
## DP: so the SetTTY() call in FreeDisplay() doesn't have to be
## DP: safeguarded on its own.
## DP: 
## DP: Note - I'm not satisfied at all with this patch, but I consider
## DP: it an ugly but working kluge, meant only to stay around as long
## DP: as upstream hasn't come up with anything better.

@DPATCH@
--- screen-4.0.3.orig/display.c	2007-08-06 22:22:20.000000000 +0200
+++ screen-4.0.3/display.c	2007-08-06 22:59:29.000000000 +0200
@@ -3137,6 +3137,8 @@
 {
   register int l;
   register char *p;
+  fd_set fd_s;
+  struct timeval sO;
 
   ASSERT(display);
   l = D_obufp - D_obuf;
@@ -3151,15 +3153,29 @@
       return;
     }
   p = D_obuf;
-  if (fcntl(D_userfd, F_SETFL, 0))
-    debug1("Warning: BLOCK fcntl failed: %d\n", errno);
+  if (fcntl(D_userfd, F_SETFL, FNBLOCK))
+    debug1("Warning: NBLOCK fcntl failed: %d\n", errno);
+  if (D_blocked == 1)
+    D_blocked = 0;
+  D_blocked_fuzz = 0;
   while (l)
     {
-      register int wr;
+      register int wr = 0;
+      sO.tv_sec = 5; sO.tv_usec = 0;
+      while (1) {
+        int sR;
+        FD_ZERO(&fd_s);
+        FD_SET(D_userfd, &fd_s);
+        sR = select(D_userfd+1, NULL, &fd_s, NULL, &sO);
+        if (!sR) {
+          debug("Timeout while waiting for display write fd to unblock\n");
+          return;
+        } else if (sR > 0) break;
+      }
       wr = write(D_userfd, p, l);
       if (wr <= 0) 
 	{
-	  if (errno == EINTR) 
+	  if (errno == EINTR || errno == EAGAIN) 
 	    continue;
 	  debug1("Writing to display: %d\n", errno);
 	  wr = l;
@@ -3172,11 +3188,6 @@
     }
   D_obuffree += l;
   D_obufp = D_obuf;
-  if (fcntl(D_userfd, F_SETFL, FNBLOCK))
-    debug1("Warning: NBLOCK fcntl failed: %d\n", errno);
-  if (D_blocked == 1)
-    D_blocked = 0;
-  D_blocked_fuzz = 0;
 }
 
 void