| 187 | } |
| 188 | |
| 189 | static int |
| 190 | eventfd_write(struct file *fp, struct uio *uio, struct ucred *active_cred, |
| 191 | int flags, struct thread *td) |
| 192 | { |
| 193 | struct eventfd *efd; |
| 194 | eventfd_t count; |
| 195 | int error; |
| 196 | |
| 197 | if (uio->uio_resid < sizeof(eventfd_t)) |
| 198 | return (EINVAL); |
| 199 | |
| 200 | error = uiomove(&count, sizeof(eventfd_t), uio); |
| 201 | if (error != 0) |
| 202 | return (error); |
| 203 | if (count == UINT64_MAX) |
| 204 | return (EINVAL); |
| 205 | |
| 206 | efd = fp->f_data; |
| 207 | mtx_lock(&efd->efd_lock); |
| 208 | retry: |
| 209 | if (UINT64_MAX - efd->efd_count <= count) { |
| 210 | if ((fp->f_flag & FNONBLOCK) != 0) { |
| 211 | mtx_unlock(&efd->efd_lock); |
| 212 | /* Do not not return the number of bytes written */ |
| 213 | uio->uio_resid += sizeof(eventfd_t); |
| 214 | return (EAGAIN); |
| 215 | } |
| 216 | error = mtx_sleep(&efd->efd_count, &efd->efd_lock, |
| 217 | PCATCH, "efdwr", 0); |
| 218 | if (error == 0) |
| 219 | goto retry; |
| 220 | } |
| 221 | if (error == 0) { |
| 222 | MPASS(UINT64_MAX - efd->efd_count > count); |
| 223 | efd->efd_count += count; |
| 224 | KNOTE_LOCKED(&efd->efd_sel.si_note, 0); |
| 225 | selwakeup(&efd->efd_sel); |
| 226 | wakeup(&efd->efd_count); |
| 227 | } |
| 228 | mtx_unlock(&efd->efd_lock); |
| 229 | |
| 230 | return (error); |
| 231 | } |
| 232 | |
| 233 | static int |
| 234 | eventfd_poll(struct file *fp, int events, struct ucred *active_cred, |
no test coverage detected