~james-page/ubuntu/saucy/openvswitch/1.12-snapshot

« back to all changes in this revision

Viewing changes to lib/latch.c

  • Committer: James Page
  • Date: 2013-08-21 10:16:57 UTC
  • mfrom: (1.1.20)
  • Revision ID: james.page@canonical.com-20130821101657-3o0z0qeiv5zkwlzi
New upstream snapshot

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
latch_init(struct latch *latch)
 
29
{
 
30
    xpipe_nonblocking(latch->fds);
 
31
}
 
32
 
 
33
/* Destroys 'latch'. */
 
34
void
 
35
latch_destroy(struct latch *latch)
 
36
{
 
37
    close(latch->fds[0]);
 
38
    close(latch->fds[1]);
 
39
}
 
40
 
 
41
/* Resets 'latch' to the unset state.  Returns true if 'latch' was previously
 
42
 * set, false otherwise. */
 
43
bool
 
44
latch_poll(struct latch *latch)
 
45
{
 
46
    char buffer[_POSIX_PIPE_BUF];
 
47
 
 
48
    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
latch_set(struct latch *latch)
 
57
{
 
58
    ignore(write(latch->fds[1], "", 1));
 
59
}
 
60
 
 
61
/* Returns true if 'latch' is set, false otherwise.  Does not reset 'latch'
 
62
 * to the unset state. */
 
63
bool
 
64
latch_is_set(const struct latch *latch)
 
65
{
 
66
    struct pollfd pfd;
 
67
    int retval;
 
68
 
 
69
    pfd.fd = latch->fds[0];
 
70
    pfd.events = POLLIN;
 
71
    do {
 
72
        retval = poll(&pfd, 1, 0);
 
73
    } while (retval < 0 && errno == EINTR);
 
74
 
 
75
    return pfd.revents & POLLIN;
 
76
}
 
77
 
 
78
/* Causes the next poll_block() to wake up when 'latch' is set. */
 
79
void
 
80
(latch_wait)(const struct latch *latch, const char *where)
 
81
{
 
82
    (poll_fd_wait)(latch->fds[0], POLLIN, where);
 
83
}