Async requests don't honor timeout param

Timeouts on the synchronous requests behave as expected, but the same exact calls with requests.async take twice as long to timeout (twice as long as the timeout specified).


On my system, timeout in synchronous requests is also flaky:

```
>>> import time, requests
>>> start = time.time(); r = requests.get('http://httpbin.org/delay/4', timeout=2.0); print time.time() - start, r.status_code
4.55748391151 200
>>> start = time.time(); r = requests.get('http://httpbin.org/delay/4', timeout=2.0); print time.time() - start, r.status_code
4.54007601738 200
>>> start = time.time(); r = requests.get('http://httpbin.org/delay/4', timeout=2.0); print time.time() - start, r.status_code
4.5993411541 200
>>> start = time.time(); r = requests.get('http://httpbin.org/delay/4', timeout=2.0); print time.time() - start, r.status_code
4.37087607384 200
>>> start = time.time(); r = requests.get('http://httpbin.org/delay/4', timeout=2.0); print time.time() - start, r.status_code
4.36421513557 200
```


But sometimes:

```
>>> start = time.time(); r = requests.get('http://httpbin.org/delay/4', timeout=2.0); print time.time() - start, r.status_code
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "requests/api.py", line 52, in get
    return request('get', url, **kwargs)
  File "requests/api.py", line 40, in request
    return s.request(method=method, url=url, **kwargs)
  File "requests/sessions.py", line 229, in request
    r.send(prefetch=prefetch)
  File "requests/models.py", line 604, in send
    raise Timeout('Request timed out.')
requests.exceptions.Timeout: Request timed out.
```


Oh, wow, this is a really cool bug. Importing `requests.async` screws up timeouts for all requests, even synchronous ones.

```

>>> import requests
>>> import time
>>> start = time.time(); r = requests.get('http://httpbin.org/delay/4', timeout=2.0); print time.time() - start, r.status_code
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "requests/api.py", line 52, in get
    return request('get', url, **kwargs)
  File "requests/api.py", line 40, in request
    return s.request(method=method, url=url, **kwargs)
  File "requests/sessions.py", line 229, in request
    r.send(prefetch=prefetch)
  File "requests/models.py", line 604, in send
    raise Timeout('Request timed out.')
requests.exceptions.Timeout: Request timed out.
>>> start = time.time(); r = requests.get('http://httpbin.org/delay/4', timeout=2.0); print time.time() - start, r.status_code
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "requests/api.py", line 52, in get
    return request('get', url, **kwargs)
  File "requests/api.py", line 40, in request
    return s.request(method=method, url=url, **kwargs)
  File "requests/sessions.py", line 229, in request
    r.send(prefetch=prefetch)
  File "requests/models.py", line 604, in send
    raise Timeout('Request timed out.')
requests.exceptions.Timeout: Request timed out.
>>> import requests.async
>>> start = time.time(); r = requests.get('http://httpbin.org/delay/4', timeout=2.0); print time.time() - start, r.status_code
4.38320612907 200
>>> start = time.time(); r = requests.get('http://httpbin.org/delay/4', timeout=2.0); print time.time() - start, r.status_code
4.67993688583 200
```


Looks like a problem with `gevent`'s monkeypatching, because this fixes it:

``` diff
diff --git a/requests/async.py b/requests/async.py
index f12cf26..ed18464 100644
--- a/requests/async.py
+++ b/requests/async.py
@@ -17,7 +17,7 @@ except ImportError:
     raise RuntimeError('Gevent is required for requests.async.')

 # Monkey-patch.
-curious_george.patch_all(thread=False, select=False)
+curious_george.patch_all(thread=False, select=False, socket=False)
```

I have no idea what to make of this.


Here's part of the problem: in principle, socket timeouts only affect socket I/O operations, i.e., `read` and `send`, not polling operations like `select` and `epoll`. (See the docs on `SO_RCVTIMEO` and `SO_SNDTIMEO` here: http://linux.die.net/man/7/socket.)

I think the fix for this is to change `requests.async.map` so that it calls `gevent.joinall` with a timeout argument, looping until all requests have either timed out or completed.

This does not explain why importing `async` is breaking ordinary synchronous requests; AFAICT sockets that have been set to non-blocking mode should still respect `SO_RCVTIMEO` during `read()`.


For some time now I can't get async to work reliably. I'm not sure if my problem is related by I get this:

```
>>> requests.request('get', 'http://httpbin.org/get').status_code
200
>>> requests.request('get', 'http://httpbin.org/get').status_code
200
>>> requests.request('get', 'http://httpbin.org/get').status_code
200
>>> requests.request('get', 'http://httpbin.org/get').status_code
200
>>> from requests import async
>>> requests.request('get', 'http://httpbin.org/get').status_code
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\users\piotr\projects\requests\requests\api.py", line 40, in request
    return s.request(method=method, url=url, **kwargs)
  File "c:\users\piotr\projects\requests\requests\sessions.py", line 229, in request
    r.send(prefetch=prefetch)
  File "c:\users\piotr\projects\requests\requests\models.py", line 598, in send
    raise ConnectionError(e)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /get
>>> requests.request('get', 'http://httpbin.org/get').status_code
200
>>> requests.request('get', 'http://httpbin.org/get').status_code
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\users\piotr\projects\requests\requests\api.py", line 40, in request
    return s.request(method=method, url=url, **kwargs)
  File "c:\users\piotr\projects\requests\requests\sessions.py", line 229, in request
    r.send(prefetch=prefetch)
  File "c:\users\piotr\projects\requests\requests\models.py", line 598, in send
    raise ConnectionError(e)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /get
```


@piotr-dobrogost doesn't reproduce for me in Linux. But yeah, it wouldn't surprise me if it were a cross-platform issue with gevent's monkeypatching. See if it goes away under the abovementioned patch?


> doesn't reproduce for me in Linux.

It's nondeterministic. Could you run it in a loop?

> See if it goes away under the abovementioned patch?

Yes, it does.
Running https://gist.github.com/2630312 without patch 3 times:

```
SYNC http errors: 0.000000%, exceptions 80.000000%
ASYNC http errors: 88.000000%, exceptions 0.000000%

SYNC http errors: 0.000000%, exceptions 84.000000%
ASYNC http errors: 90.000000%, exceptions 0.000000%

SYNC http errors: 0.000000%, exceptions 90.000000%
ASYNC http errors: 96.000000%, exceptions 0.000000%
```

Running https://gist.github.com/2630312 with patch 3 times:

3x

```
SYNC http errors: 0.000000%, exceptions 0.000000%
ASYNC http errors: 0.000000%, exceptions 0.000000%
```


Ran it three times against the unpatched code, no errors. I'm pretty sure it's cross-platform.


```
[shivaram@good-fortune ~/workspace/requests]$ python ./requests-issue-500.py 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
SYNC http errors: 0.000000%, exceptions 0.000000%
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
ASYNC http errors: 0.000000%, exceptions 0.000000%
```


I shared https://github.com/kennethreitz/requests/issues/500#issuecomment-5508478 link on freenode #gevent IRC channel and colinmarc replied:

> the gevent socket module keeps track of what the actual timeout on the socket is supposed to be
> so if you settimeout(0.0) on a gevent socket, it will still throw EWOULDBLOCK like normal
> and if you settimeout(1.0), then it will create a Timeout object and throw the exception after a second, but still yield back to the loop in that second
> so it should behave the same, yeah


I looked in the gevent codebase and their current socket timeout test case doesn't cover this issue, only that timeout on `read` is respected. I'll see if I can work up a test case for this behavior.


Async is removed from requests now. A new module, [grequests](https://github.com/kennethreitz/grequests) will replace it.