summaryrefslogtreecommitdiff
path: root/open_issues/libpthread_cancellation_points.mdwn
blob: 48f1acf5061e7ef9c7b95f799d82986fec7a5055 (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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
[[!meta copyright="Copyright © 2013 Free Software Foundation, Inc."]]

[[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable
id="license" text="Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License, Version 1.2 or
any later version published by the Free Software Foundation; with no Invariant
Sections, no Front-Cover Texts, and no Back-Cover Texts.  A copy of the license
is included in the section entitled [[GNU Free Documentation
License|/fdl]]."]]"""]]

[[!meta title="cancellation points are not cancelling threads"]]

[[!tag open_issue_libpthread]]

    #include <pthread.h>
    #include <stdio.h>
    #include <sys/select.h>
    #include <unistd.h>
    
    void *f (void*foo)
    {
        char buf[128];
	//pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
	while (1) {
	    read (0, buf, sizeof(buf));
	}
    }
    int main (void) {
        pthread_t t;
	pthread_create (&t, NULL, f, NULL);
	sleep (1);
	pthread_cancel (t);
	pthread_join (t, NULL);
	exit(0);
    }

read() is not behaving as a cancellation point, only setting the cancel
type to asynchronous permits this testcase to terminate. We do have the
pthread_setcanceltype glibc/libpthread hook in the forward structure, but we are
not using it: the LIBC_CANCEL_ASYNC macros are void, and we're not using them in
the mig msg call either.


# Provenance

## IRC, OFTC, #debian-hurd, 2013-04-15

    <paravoid> so, let me say a few things about the bug in the first place
    <paravoid> the package builds and runs a test suite
    <paravoid> the second test in the test suite blocks forever
    <paravoid> a blocked pthread_join is what I see
    <paravoid> I'm unsure why
    <paravoid> have you seen anything like it before?
    <youpi> whenever the thread doesn't actually terminate, sure
    <youpi> what is the thread usually blocked on when you cancel it?
    <paravoid> this is a hurd-specific issue
    <paravoid> works on all other arches
    <youpi> could be just that all other archs have more relaxed behavior
    <youpi> thus the question of what exactly is supposed to be happening
    <youpi> apparently it is inside a select?
    <youpi> it seems select is not cancellable here
    <pinotree> wasn't the patch you sent?
    <youpi> no, my patch was about signals
    <youpi> not cancellation
    <pinotree> k
    <youpi> (even if that could be related, of course)
    <paravoid> how did you see that?
    <paravoid> what's the equivalent of strace?
    <youpi> thread 3 is inside _hurd_select
    <paravoid> thread 1 is blocked on join
    <paravoid> but the code is
    <paravoid>     if(gdmaps->reload_thread_spawned) {
    <paravoid>         pthread_cancel(gdmaps->reload_tid);
    <paravoid>         pthread_join(gdmaps->reload_tid, NULL);
    <paravoid>     }
    <paravoid> so cancel should have killed the thread
    <youpi> cancelling a thread is a complex matter
    <youpi> there are cancellation points
    <youpi> e.g. a thread performing while(1); can't be cancelled
    <paravoid> thread 3 is just a libev event loop
    <youpi> yes, "just" calling poll, the most complex system call of unix :)
    <youpi> paravoid: anyway, don't look for a bug in your program, it's most
      likely a bug in glibc, thanks for the report
    <paravoid> I think it all boils down to a problem cancelling a thread in
      poll()
    <youpi> yes
    <youpi> paravoid: ok, actually with the latest libc it does work
    <paravoid> oh?
    <youpi> where latest = not uploaded yet :/
    <paravoid> did you test this on exodar?
    <youpi> pinotree: that's the libpthread_cancellation.diff I guess
    <paravoid> because I commented out the join :)
    <youpi> paravoid:  in the root, yes
    <youpi> well, I tried my own program
    <paravoid> oh, okay
    <youpi> which is indeed hanging inside select (or just read) in the chroot
    <youpi> but not in the root
    <pinotree> ah, richard's patch
    <paravoid> url?
    <youpi> I've installed the build-dep in the root, if you want to try
    <paravoid> strange that root is newer than the chroot :)
    <youpi> paravoid: it's the usual eglibc debian source
    <paravoid> tried in root, still fails
    <youpi> could you keep the process running?
    <paravoid> done
    <youpi> Mmm, but the thread running gdmaps_reload_thread never set the
      cancel type to async?
    <youpi> that said I guess read and select are supposed to be cancellation
      points
    <youpi> thus cancel_deferred should be working, but they are not
    <youpi> it seems it's cancellation points which have just not been
      implemented
    <youpi> (they happen to be one of the most obscure things in posix)


## IRC, freenode, #hurd, 2013-04-15

    <youpi> but yes, there is still an issue, with PTHREAD_CANCEL_DEFERRED
    <youpi> how calls like read() or select() are supposed to test
      cancellation?
    <pinotree> iirc there are the LIBC_CANCEL_* macros in glibc
    <pinotree> eg sysdeps/unix/sysv/linux/pread.c
    <youpi> yes
    <youpi> but in our libpthredaD?
    <pinotree> could it be we lack the libpthread → glibc bridge of
      cancellation stuff?
    <youpi> we do have pthread_setcancelstate/type forwards
    <youpi> but it seems the default LIBC_CANCEL_ASYNC is void
    <pinotree> i mean, so when you cancel a thread, you can get that cancel
      status in libc proper, just like it seems done with LIBC_CANCEL_* macros
      and nptl
    <youpi> as I said, the bridge is there
    <youpi> we're just not using it in glibc
    <youpi> I'm writing an open_issues page


### IRC, freenode, #hurd, 2013-04-16

    <braunr> youpi: yes, we said some time ago that it was lacking