Commit 50a25535 authored by Denis Bilenko's avatar Denis Bilenko

move c-ares wrappers from gevent.core to gevent.ares; make it optional in setup.py

in gevent.ares module:
 - rename ares_channel to channel
 - rename ares_strerror() to ares.strerror()
 - remove _strerror()
 - do not use gevent_handle_error C function, use loop.handle_error
 - do not use loop and io watcher definitions (use Python calls instead of fast vtab calls)

add python.pxd with a few common python functions
do not include c-ares stuff, compile it separately
add inet_ntop.c to gevent/ since it's not exported by c-ares and we use it

make ares extension optional - retry setup.py command if it failed

--HG--
rename : gevent/cares.pxi => gevent/ares.pyx
parent 73b25755
This diff is collapsed.
`#' DO NOT EDIT -- this file is auto generated from __file__ on syscmd(date)
cimport cython
cimport libev
from python cimport *
__all__ = ['get_version',
......@@ -12,24 +13,6 @@ __all__ = ['get_version',
'loop']
cdef extern from "Python.h":
struct PyObject:
pass
ctypedef PyObject* PyObjectPtr "PyObject*"
void Py_INCREF(PyObjectPtr)
void Py_DECREF(PyObjectPtr)
void Py_XDECREF(PyObjectPtr)
int Py_ReprEnter(PyObjectPtr)
void Py_ReprLeave(PyObjectPtr)
int PyCallable_Check(PyObjectPtr)
cdef extern from "frameobject.h":
ctypedef struct PyThreadState:
PyObjectPtr exc_type
PyObjectPtr exc_value
PyObjectPtr exc_traceback
PyThreadState* PyThreadState_GET()
cdef extern from "callbacks.h":
void gevent_callback_io(libev.ev_loop, void*, int)
void gevent_callback_timer(libev.ev_loop, void*, int)
......@@ -628,6 +611,3 @@ def set_exc_info(object type, object value):
Py_INCREF(<PyObjectPtr>value)
tstate.exc_value = <PyObjectPtr>value
tstate.exc_traceback = NULL
include "cares.pxi"
#include "Python.h"
#include "ares_setup.h"
#include "ares__close_sockets.c"
#include "ares_data.c"
#include "ares_destroy.c"
#include "ares_expand_name.c"
#include "ares_free_hostent.c"
#include "ares_free_string.c"
#include "ares_gethostbyaddr.c"
#include "ares_gethostbyname.c"
#include "ares__get_hostent.c"
#include "ares_getnameinfo.c"
#include "ares_init.c"
#include "ares_library_init.c"
#include "ares_llist.c"
#include "ares_mkquery.c"
#include "ares_nowarn.c"
#include "ares_options.c"
#include "ares_parse_aaaa_reply.c"
#include "ares_parse_a_reply.c"
#include "ares_parse_ptr_reply.c"
#include "ares_process.c"
#include "ares_query.c"
#include "ares__read_line.c"
#include "ares_search.c"
#include "ares_send.c"
#include "ares_strerror.c"
//#include "ares_timeout.c"
#include "ares__timeval.c"
//#include "ares_version.c"
#include "bitncmp.c"
#include "inet_net_pton.c"
#include "inet_ntop.c"
#ifdef _WIN32
#include "windows_port.c"
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#include "ares.h"
#include "inet_ntop.c"
static PyObject* _socket_error = 0;
static PyObject* _socket_gaierror = 0;
static inline PyObject* get_socket_object(PyObject** pobject, const char* name, int incref)
static PyObject*
get_socket_object(PyObject** pobject, const char* name, int incref)
{
if (!*pobject) {
PyObject* _socket;
......@@ -64,10 +38,18 @@ static inline PyObject* get_socket_object(PyObject** pobject, const char* name,
return *pobject;
}
static inline PyObject* get_socket_error() { return get_socket_object(&_socket_error, "error", 1); }
static inline PyObject* get_socket_gaierror() { return get_socket_object(&_socket_gaierror, "gaierror", 1); }
static PyObject*
get_socket_error() {
return get_socket_object(&_socket_error, "error", 1);
}
static PyObject*
get_socket_gaierror() {
return get_socket_object(&_socket_gaierror, "gaierror", 1);
}
static int gevent_append_addr(PyObject* list, int family, void* src, char* tmpbuf, size_t tmpsize) {
static int
gevent_append_addr(PyObject* list, int family, void* src, char* tmpbuf, size_t tmpsize) {
int status = -1;
PyObject* tmp;
if (ares_inet_ntop(family, src, tmpbuf, tmpsize)) {
......@@ -154,7 +136,8 @@ parse_h_addr_list(struct hostent *h)
}
static inline int gevent_make_sockaddr(char* hostp, int port, int flowinfo, int scope_id, struct sockaddr_in6* sa6) {
static int
gevent_make_sockaddr(char* hostp, int port, int flowinfo, int scope_id, struct sockaddr_in6* sa6) {
if ( ares_inet_pton(AF_INET, hostp, &((struct sockaddr_in*)sa6)->sin_addr.s_addr) > 0 ) {
((struct sockaddr_in*)sa6)->sin_family = AF_INET;
((struct sockaddr_in*)sa6)->sin_port = htons(port);
......
/* copied from c-ares since we need this in dnshelper.c and c-ares does not export these functions */
/* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#define NS_IN6ADDRSZ 16
#define NS_INT16SZ 2
#ifdef SPRINTF_CHAR
# define SPRINTF(x) strlen(sprintf/**/x)
#else
# define SPRINTF(x) ((size_t)sprintf x)
#endif
/*
* WARNING: Don't even consider trying to compile this on a system where
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
*/
static const char *inet_ntop4(const unsigned char *src, char *dst, size_t size);
static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size);
/* char *
* inet_ntop(af, src, dst, size)
* convert a network format address to presentation format.
* return:
* pointer to presentation format address (`dst'), or NULL (see errno).
* note:
* On Windows we store the error in the thread errno, not
* in the winsock error code. This is to avoid loosing the
* actual last winsock error. So use macro ERRNO to fetch the
* errno this funtion sets when returning NULL, not SOCKERRNO.
* author:
* Paul Vixie, 1996.
*/
static const char *
ares_inet_ntop(int af, const void *src, char *dst, size_t size)
{
switch (af)
{
case AF_INET:
return (inet_ntop4(src, dst, size));
case AF_INET6:
return (inet_ntop6(src, dst, size));
default:
SET_ERRNO(EAFNOSUPPORT);
return (NULL);
}
/* NOTREACHED */
}
/* const char *
* inet_ntop4(src, dst, size)
* format an IPv4 address, more or less like inet_ntoa()
* return:
* `dst' (as a const)
* notes:
* (1) uses no statics
* (2) takes a unsigned char* not an in_addr as input
* author:
* Paul Vixie, 1996.
*/
static const char *
inet_ntop4(const unsigned char *src, char *dst, size_t size)
{
static const char fmt[] = "%u.%u.%u.%u";
char tmp[sizeof "255.255.255.255"];
if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size)
{
SET_ERRNO(ENOSPC);
return (NULL);
}
strcpy(dst, tmp);
return (dst);
}
/* const char *
* inet_ntop6(src, dst, size)
* convert IPv6 binary address into presentation (printable) format
* author:
* Paul Vixie, 1996.
*/
static const char *
inet_ntop6(const unsigned char *src, char *dst, size_t size)
{
/*
* Note that int32_t and int16_t need only be "at least" large enough
* to contain a value of the specified size. On some systems, like
* Crays, there is no such thing as an integer variable with 16 bits.
* Keep this in mind if you think this function should have been coded
* to use pointer overlays. All the world's not a VAX.
*/
char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
char *tp;
struct {
long base;
long len;
} best, cur;
unsigned long words[NS_IN6ADDRSZ / NS_INT16SZ];
int i;
/*
* Preprocess:
* Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding.
*/
memset(words, '\0', sizeof(words));
for (i = 0; i < NS_IN6ADDRSZ; i++)
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
best.base = -1;
cur.base = -1;
best.len = 0;
cur.len = 0;
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
{
if (words[i] == 0)
{
if (cur.base == -1)
cur.base = i, cur.len = 1;
else
cur.len++;
}
else
{
if (cur.base != -1)
{
if (best.base == -1 || cur.len > best.len)
best = cur;
cur.base = -1;
}
}
}
if (cur.base != -1)
{
if (best.base == -1 || cur.len > best.len)
best = cur;
}
if (best.base != -1 && best.len < 2)
best.base = -1;
/*
* Format the result.
*/
tp = tmp;
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
{
/* Are we inside the best run of 0x00's? */
if (best.base != -1 && i >= best.base &&
i < (best.base + best.len))
{
if (i == best.base)
*tp++ = ':';
continue;
}
/* Are we following an initial run of 0x00s or any real hex? */
if (i != 0)
*tp++ = ':';
/* Is this address an encapsulated IPv4? */
if (i == 6 && best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
{
if (!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp)))
return (NULL);
tp += strlen(tp);
break;
}
tp += SPRINTF((tp, "%lx", words[i]));
}
/* Was it a trailing run of 0x00's? */
if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ))
*tp++ = ':';
*tp++ = '\0';
/*
* Check for overflow, copy, and we're done.
*/
if ((size_t)(tp - tmp) > size)
{
SET_ERRNO(ENOSPC);
return (NULL);
}
strcpy(dst, tmp);
return (dst);
}
cdef extern from "Python.h":
struct PyObject:
pass
ctypedef PyObject* PyObjectPtr "PyObject*"
void Py_INCREF(PyObjectPtr)
void Py_DECREF(PyObjectPtr)
void Py_XDECREF(PyObjectPtr)
int Py_ReprEnter(PyObjectPtr)
void Py_ReprLeave(PyObjectPtr)
int PyCallable_Check(PyObjectPtr)
cdef extern from "frameobject.h":
ctypedef struct PyThreadState:
PyObjectPtr exc_type
PyObjectPtr exc_value
PyObjectPtr exc_traceback
PyThreadState* PyThreadState_GET()
......@@ -2,7 +2,7 @@ import os
from _socket import getservbyname, getaddrinfo, gaierror, error
from gevent.hub import Waiter, get_hub
from gevent.socket import AF_UNSPEC, AF_INET, AF_INET6, SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, AI_NUMERICHOST, EAI_SERVICE
from gevent.core import ares_channel
from gevent.ares import channel
__all__ = ['Resolver']
......@@ -10,7 +10,7 @@ __all__ = ['Resolver']
class Resolver(object):
ares_class = ares_channel
ares_class = channel
def __init__(self, hub=None, **kwargs):
if hub is None:
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment