Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2013 Nicira, Inc.
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at:
7 : : *
8 : : * http://www.apache.org/licenses/LICENSE-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : #include <config.h>
18 : :
19 : : #include "latch.h"
20 : : #include <errno.h>
21 : : #include <poll.h>
22 : : #include <unistd.h>
23 : : #include "poll-loop.h"
24 : : #include "socket-util.h"
25 : :
26 : : /* Initializes 'latch' as initially unset. */
27 : : void
28 : 5989 : latch_init(struct latch *latch)
29 : : {
30 : 5989 : xpipe_nonblocking(latch->fds);
31 : 5989 : }
32 : :
33 : : /* Destroys 'latch'. */
34 : : void
35 : 3116 : latch_destroy(struct latch *latch)
36 : : {
37 : 3116 : close(latch->fds[0]);
38 : 3116 : close(latch->fds[1]);
39 : 3116 : }
40 : :
41 : : /* Resets 'latch' to the unset state. Returns true if 'latch' was previously
42 : : * set, false otherwise. */
43 : : bool
44 : 231241 : latch_poll(struct latch *latch)
45 : : {
46 : : char buffer[_POSIX_PIPE_BUF];
47 : :
48 : 231241 : return read(latch->fds[0], buffer, sizeof buffer) > 0;
49 : : }
50 : :
51 : : /* Sets 'latch'.
52 : : *
53 : : * Calls are not additive: a single latch_poll() clears out any number of
54 : : * latch_set(). */
55 : : void
56 : 121170 : latch_set(struct latch *latch)
57 : : {
58 : 121170 : ignore(write(latch->fds[1], "", 1));
59 : 121170 : }
60 : :
61 : : /* Returns true if 'latch' is set, false otherwise. Does not reset 'latch'
62 : : * to the unset state. */
63 : : bool
64 : 86661 : latch_is_set(const struct latch *latch)
65 : : {
66 : : struct pollfd pfd;
67 : : int retval;
68 : :
69 : 86661 : pfd.fd = latch->fds[0];
70 : 86661 : pfd.events = POLLIN;
71 : : do {
72 : 86661 : retval = poll(&pfd, 1, 0);
73 [ - + ][ # # ]: 86661 : } while (retval < 0 && errno == EINTR);
74 : :
75 : 86661 : return pfd.revents & POLLIN;
76 : : }
77 : :
78 : : /* Causes the next poll_block() to wake up when 'latch' is set.
79 : : *
80 : : * ('where' is used in debug logging. Commonly one would use latch_wait() to
81 : : * automatically provide the caller's source file and line number for
82 : : * 'where'.) */
83 : : void
84 : 306618 : latch_wait_at(const struct latch *latch, const char *where)
85 : : {
86 : 306618 : poll_fd_wait_at(latch->fds[0], POLLIN, where);
87 : 306619 : }
|