]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/pthread/aio_cancel.c
Update.
[thirdparty/glibc.git] / sysdeps / pthread / aio_cancel.c
1 /* Cancel requests associated with given file descriptor.
2 Copyright (C) 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
20
21
22 /* We use an UGLY hack to prevent gcc from finding us cheating. The
23 implementation of aio_cancel and aio_cancel64 are identical and so
24 we want to avoid code duplication by using aliases. But gcc sees
25 the different parameter lists and prints a warning. We define here
26 a function so that aio_cancel64 has no prototype. */
27 #ifndef aio_cancel
28 #define aio_cancel64 XXX
29 #include <aio.h>
30 /* And undo the hack. */
31 #undef aio_cancel64
32 #endif
33
34 #include <assert.h>
35 #include <errno.h>
36
37 #include "aio_misc.h"
38
39
40 int
41 aio_cancel (fildes, aiocbp)
42 int fildes;
43 struct aiocb *aiocbp;
44 {
45 struct requestlist *req = NULL;
46 int result = AIO_ALLDONE;
47
48 /* If fildes is invalid, error. */
49 if (fcntl (fildes, F_GETFL) < 0)
50 {
51 __set_errno (EBADF);
52 return -1;
53 }
54
55 /* Request the mutex. */
56 pthread_mutex_lock (&__aio_requests_mutex);
57
58 /* We are asked to cancel a specific AIO request. */
59 if (aiocbp != NULL)
60 {
61 /* If the AIO request is not for this descriptor it has no value
62 to look for the request block. */
63 if (aiocbp->aio_fildes == fildes)
64 {
65 struct requestlist *last = NULL;
66
67 req = __aio_find_req_fd (fildes);
68
69 if (req == NULL)
70 {
71 not_found:
72 pthread_mutex_unlock (&__aio_requests_mutex);
73 __set_errno (EINVAL);
74 return -1;
75 }
76
77 while (req->aiocbp != (aiocb_union *) aiocbp)
78 {
79 last = req;
80 req = req->next_prio;
81 if (req == NULL)
82 goto not_found;
83 }
84
85 /* Don't remove the entry if a thread is already working on it. */
86 if (req->running == allocated)
87 {
88 result = AIO_NOTCANCELED;
89 req = NULL;
90 }
91 else
92 {
93 /* We can remove the entry. */
94 __aio_remove_request (last, req, 0);
95
96 result = AIO_CANCELED;
97
98 req->next_prio = NULL;
99 }
100 }
101 }
102 else
103 {
104 /* Find the beginning of the list of all requests for this
105 desriptor. */
106 req = __aio_find_req_fd (fildes);
107
108 /* If any request is worked on by a thread it must be the first.
109 So either we can delete all requests or all but the first. */
110 if (req != NULL)
111 {
112 if (req->running == allocated)
113 {
114 struct requestlist *old = req;
115 req = req->next_prio;
116 old->next_prio = NULL;
117
118 result = AIO_NOTCANCELED;
119
120 if (req != NULL)
121 __aio_remove_request (old, req, 1);
122 }
123 else
124 {
125 result = AIO_CANCELED;
126
127 /* We can remove the entry. */
128 __aio_remove_request (NULL, req, 1);
129 }
130 }
131 }
132
133 /* Mark requests as canceled and send signal. */
134 while (req != NULL)
135 {
136 struct requestlist *old = req;
137 assert (req->running == yes || req->running == queued);
138 req->aiocbp->aiocb.__error_code = ECANCELED;
139 req->aiocbp->aiocb.__return_value = -1;
140 __aio_notify (req);
141 req = req->next_prio;
142 __aio_free_request (old);
143 }
144
145 /* Release the mutex. */
146 pthread_mutex_unlock (&__aio_requests_mutex);
147
148 return result;
149 }
150
151 #ifndef aio_cancel
152 weak_alias (aio_cancel, aio_cancel64)
153 #endif