~yolanda.robla/ubuntu/trusty/nodejs/add_distribution

« back to all changes in this revision

Viewing changes to deps/uv/src/unix/cares.c

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2013-08-14 00:16:46 UTC
  • mfrom: (7.1.40 sid)
  • Revision ID: package-import@ubuntu.com-20130814001646-bzlysfh8sd6mukbo
Tags: 0.10.15~dfsg1-4
* Update 2005 patch, adding a handful of tests that can fail on
  slow platforms.
* Add 1004 patch to fix test failures when writing NaN to buffer
  on mipsel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
 
 *
3
 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
4
 
 * of this software and associated documentation files (the "Software"), to
5
 
 * deal in the Software without restriction, including without limitation the
6
 
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
 
 * sell copies of the Software, and to permit persons to whom the Software is
8
 
 * furnished to do so, subject to the following conditions:
9
 
 *
10
 
 * The above copyright notice and this permission notice shall be included in
11
 
 * all copies or substantial portions of the Software.
12
 
 *
13
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19
 
 * IN THE SOFTWARE.
20
 
 */
21
 
 
22
 
#include "uv.h"
23
 
#include "internal.h"
24
 
 
25
 
#include <assert.h>
26
 
#include <errno.h>
27
 
#include <stdlib.h>
28
 
 
29
 
 
30
 
/*
31
 
 * This is called once per second by loop->timer. It is used to
32
 
 * constantly callback into c-ares for possibly processing timeouts.
33
 
 */
34
 
static void uv__ares_timeout(struct ev_loop* ev, struct ev_timer* watcher,
35
 
    int revents) {
36
 
  uv_loop_t* loop = ev_userdata(ev);
37
 
 
38
 
  assert(ev == loop->ev);
39
 
  assert((uv_loop_t*)watcher->data == loop);
40
 
  assert(watcher == &loop->timer);
41
 
  assert(revents == EV_TIMER);
42
 
  assert(!uv_ares_handles_empty(loop));
43
 
 
44
 
  ares_process_fd(loop->channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
45
 
}
46
 
 
47
 
 
48
 
static void uv__ares_io(struct ev_loop* ev, struct ev_io* watcher,
49
 
    int revents) {
50
 
  uv_loop_t* loop = ev_userdata(ev);
51
 
 
52
 
  assert(ev == loop->ev);
53
 
 
54
 
  /* Reset the idle timer */
55
 
  ev_timer_again(ev, &loop->timer);
56
 
 
57
 
  /* Process DNS responses */
58
 
  ares_process_fd(loop->channel,
59
 
      revents & EV_READ ? watcher->fd : ARES_SOCKET_BAD,
60
 
      revents & EV_WRITE ? watcher->fd : ARES_SOCKET_BAD);
61
 
}
62
 
 
63
 
 
64
 
/* Allocates and returns a new uv_ares_task_t */
65
 
static uv_ares_task_t* uv__ares_task_create(int fd) {
66
 
  uv_ares_task_t* h = malloc(sizeof(uv_ares_task_t));
67
 
 
68
 
  if (h == NULL) {
69
 
    uv_fatal_error(ENOMEM, "malloc");
70
 
    return NULL;
71
 
  }
72
 
 
73
 
  h->sock = fd;
74
 
 
75
 
  ev_io_init(&h->read_watcher, uv__ares_io, fd, EV_READ);
76
 
  ev_io_init(&h->write_watcher, uv__ares_io, fd, EV_WRITE);
77
 
 
78
 
  h->read_watcher.data = h;
79
 
  h->write_watcher.data = h;
80
 
 
81
 
  return h;
82
 
}
83
 
 
84
 
 
85
 
/* Callback from ares when socket operation is started */
86
 
static void uv__ares_sockstate_cb(void* data, ares_socket_t sock,
87
 
    int read, int write) {
88
 
  uv_loop_t* loop = data;
89
 
  uv_ares_task_t* h;
90
 
 
91
 
  assert((uv_loop_t*)loop->timer.data == loop);
92
 
 
93
 
  h = uv_find_ares_handle(loop, sock);
94
 
 
95
 
  if (read || write) {
96
 
    if (!h) {
97
 
      /* New socket */
98
 
 
99
 
      /* If this is the first socket then start the timer. */
100
 
      if (!ev_is_active(&loop->timer)) {
101
 
        assert(uv_ares_handles_empty(loop));
102
 
        ev_timer_again(loop->ev, &loop->timer);
103
 
      }
104
 
 
105
 
      h = uv__ares_task_create(sock);
106
 
      uv_add_ares_handle(loop, h);
107
 
    }
108
 
 
109
 
    if (read) {
110
 
      ev_io_start(loop->ev, &h->read_watcher);
111
 
    } else {
112
 
      ev_io_stop(loop->ev, &h->read_watcher);
113
 
    }
114
 
 
115
 
    if (write) {
116
 
      ev_io_start(loop->ev, &h->write_watcher);
117
 
    } else {
118
 
      ev_io_stop(loop->ev, &h->write_watcher);
119
 
    }
120
 
 
121
 
  } else {
122
 
    /*
123
 
     * read == 0 and write == 0 this is c-ares's way of notifying us that
124
 
     * the socket is now closed. We must free the data associated with
125
 
     * socket.
126
 
     */
127
 
    assert(h && "When an ares socket is closed we should have a handle for it");
128
 
 
129
 
    ev_io_stop(loop->ev, &h->read_watcher);
130
 
    ev_io_stop(loop->ev, &h->write_watcher);
131
 
 
132
 
    uv_remove_ares_handle(h);
133
 
    free(h);
134
 
 
135
 
    if (uv_ares_handles_empty(loop)) {
136
 
      ev_timer_stop(loop->ev, &loop->timer);
137
 
    }
138
 
  }
139
 
}
140
 
 
141
 
 
142
 
/* c-ares integration initialize and terminate */
143
 
/* TODO: share this with windows? */
144
 
int uv_ares_init_options(uv_loop_t* loop, ares_channel *channelptr,
145
 
    struct ares_options *options, int optmask) {
146
 
  int rc;
147
 
 
148
 
  /* only allow single init at a time */
149
 
  if (loop->channel != NULL) {
150
 
    uv__set_artificial_error(loop, UV_EALREADY);
151
 
    return -1;
152
 
  }
153
 
 
154
 
  /* set our callback as an option */
155
 
  options->sock_state_cb = uv__ares_sockstate_cb;
156
 
  options->sock_state_cb_data = loop;
157
 
  optmask |= ARES_OPT_SOCK_STATE_CB;
158
 
 
159
 
  /* We do the call to ares_init_option for caller. */
160
 
  rc = ares_init_options(channelptr, options, optmask);
161
 
 
162
 
  /* if success, save channel */
163
 
  if (rc == ARES_SUCCESS) {
164
 
    loop->channel = *channelptr;
165
 
  } 
166
 
 
167
 
  /*
168
 
   * Initialize the timeout timer. The timer won't be started until the
169
 
   * first socket is opened.
170
 
   */
171
 
  ev_timer_init(&loop->timer, uv__ares_timeout, 1., 1.);
172
 
  loop->timer.data = loop;
173
 
 
174
 
  return rc;
175
 
}
176
 
 
177
 
 
178
 
/* TODO share this with windows? */
179
 
void uv_ares_destroy(uv_loop_t* loop, ares_channel channel) {
180
 
  /* only allow destroy if did init */
181
 
  if (loop->channel) {
182
 
    ev_timer_stop(loop->ev, &loop->timer);
183
 
    ares_destroy(channel);
184
 
    loop->channel = NULL;
185
 
  }
186
 
}