~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to srclib/apr/support/unix/waitio.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
 
2
 * applicable.
 
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 "apr_arch_file_io.h"
 
18
#include "apr_arch_networkio.h"
 
19
#include "apr_poll.h"
 
20
#include "apr_errno.h"
 
21
#include "apr_support.h"
 
22
 
 
23
/* The only case where we don't use wait_for_io_or_timeout is on
 
24
 * pre-BONE BeOS, so this check should be sufficient and simpler */
 
25
#if !BEOS_R5
 
26
#define USE_WAIT_FOR_IO
 
27
#endif
 
28
 
 
29
#ifdef USE_WAIT_FOR_IO
 
30
 
 
31
#ifdef WAITIO_USES_POLL
 
32
 
 
33
#ifdef HAVE_POLL_H
 
34
#include <poll.h>
 
35
#endif
 
36
#ifdef HAVE_SYS_POLL_H
 
37
#include <sys/poll.h>
 
38
#endif
 
39
 
 
40
apr_status_t apr_wait_for_io_or_timeout(apr_file_t *f, apr_socket_t *s,
 
41
                                        int for_read)
 
42
{
 
43
    struct pollfd pfd;
 
44
    int rc, timeout;
 
45
 
 
46
    timeout    = f        ? f->timeout / 1000 : s->timeout / 1000;
 
47
    pfd.fd     = f        ? f->filedes        : s->socketdes;
 
48
    pfd.events = for_read ? POLLIN            : POLLOUT;
 
49
 
 
50
    do {
 
51
        rc = poll(&pfd, 1, timeout);
 
52
    } while (rc == -1 && errno == EINTR);
 
53
    if (rc == 0) {
 
54
        return APR_TIMEUP;
 
55
    }
 
56
    else if (rc > 0) {
 
57
        return APR_SUCCESS;
 
58
    }
 
59
    else {
 
60
        return errno;
 
61
    }
 
62
}
 
63
 
 
64
#else /* !WAITIO_USES_POLL */
 
65
 
 
66
apr_status_t apr_wait_for_io_or_timeout(apr_file_t *f, apr_socket_t *s,
 
67
                                        int for_read)
 
68
{
 
69
    apr_interval_time_t timeout;
 
70
    apr_pollfd_t pfd;
 
71
    int type = for_read ? APR_POLLIN : APR_POLLOUT;
 
72
    apr_pollset_t *pollset;
 
73
    apr_status_t status;
 
74
 
 
75
    /* TODO - timeout should be less each time through this loop */
 
76
    if (f) {
 
77
        pfd.desc_type = APR_POLL_FILE;
 
78
        pfd.desc.f = f;
 
79
 
 
80
        pollset = f->pollset;
 
81
        if (pollset == NULL) {
 
82
            status = apr_pollset_create(&(f->pollset), 1, f->pool, 0);
 
83
            if (status != APR_SUCCESS) {
 
84
                return status;
 
85
            }
 
86
            pollset = f->pollset;
 
87
        }
 
88
        timeout = f->timeout;
 
89
    }
 
90
    else {
 
91
        pfd.desc_type = APR_POLL_SOCKET;
 
92
        pfd.desc.s = s;
 
93
 
 
94
        pollset = s->pollset;
 
95
        timeout = s->timeout;
 
96
    }
 
97
    pfd.reqevents = type;
 
98
 
 
99
    /* Remove the object if it was in the pollset, then add in the new
 
100
     * object with the correct reqevents value. Ignore the status result
 
101
     * on the remove, because it might not be in there (yet).
 
102
     */
 
103
    (void) apr_pollset_remove(pollset, &pfd);
 
104
 
 
105
    /* ### check status code */
 
106
    (void) apr_pollset_add(pollset, &pfd);
 
107
 
 
108
    do {
 
109
        int numdesc;
 
110
        const apr_pollfd_t *pdesc;
 
111
 
 
112
        status = apr_pollset_poll(pollset, timeout, &numdesc, &pdesc);
 
113
 
 
114
        if (numdesc == 1 && (pdesc[0].rtnevents & type) != 0) {
 
115
            return APR_SUCCESS;
 
116
        }
 
117
    } while (APR_STATUS_IS_EINTR(status));
 
118
 
 
119
    return status;
 
120
}
 
121
#endif /* WAITIO_USES_POLL */
 
122
 
 
123
#endif /* USE_WAIT_FOR_IO */