Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gevent
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gevent
Commits
576a756d
Commit
576a756d
authored
Sep 15, 2012
by
Vitaly Kruglikov
Committed by
Denis Bilenko
Sep 22, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
os: emulate non-blocking API in posix_read/write
parent
fac300d1
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
69 additions
and
5 deletions
+69
-5
gevent/os.py
gevent/os.py
+11
-5
greentest/test__os.py
greentest/test__os.py
+58
-0
No files found.
gevent/os.py
View file @
576a756d
...
...
@@ -32,7 +32,7 @@ def _map_errors(func, *args):
try
:
return
func
(
*
args
)
except
IOError
,
e
:
# IOError is struct
e
red like OSError in that it has two args: an error
# IOError is struct
u
red like OSError in that it has two args: an error
# number and a error string. So we can just re-raise OSError passing it
# the IOError args. If at some point we want to catch other errors and
# map those to OSError as well, we need to make sure that it follows
...
...
@@ -48,13 +48,16 @@ def posix_read(fd, n):
hub
,
event
=
None
,
None
while
True
:
flags
=
_map_errors
(
fcntl
.
fcntl
,
fd
,
fcntl
.
F_GETFL
,
0
)
if
not
flags
&
os
.
O_NONBLOCK
:
blocking_fd
=
not
bool
(
flags
&
os
.
O_NONBLOCK
)
if
blocking_fd
:
_map_errors
(
fcntl
.
fcntl
,
fd
,
fcntl
.
F_SETFL
,
flags
|
os
.
O_NONBLOCK
)
try
:
return
_read
(
fd
,
n
)
except
OSError
,
e
:
if
e
.
errno
not
in
ignored_errors
:
raise
if
e
.
errno
==
EAGAIN
and
not
blocking_fd
:
raise
sys
.
exc_clear
()
finally
:
# Be sure to restore the fcntl flags before we switch into the hub.
...
...
@@ -62,7 +65,7 @@ def posix_read(fd, n):
# (e.g. when using ttys/ptys). Those other file descriptors are
# impacted by our change of flags, so we should restore them
# before any other code can possibly run.
if
not
flags
&
os
.
O_NONBLOCK
:
if
blocking_fd
:
_map_errors
(
fcntl
.
fcntl
,
fd
,
fcntl
.
F_SETFL
,
flags
)
if
hub
is
None
:
hub
=
get_hub
()
...
...
@@ -76,17 +79,20 @@ def posix_write(fd, buf):
hub
,
event
=
None
,
None
while
True
:
flags
=
_map_errors
(
fcntl
.
fcntl
,
fd
,
fcntl
.
F_GETFL
,
0
)
if
not
flags
&
os
.
O_NONBLOCK
:
blocking_fd
=
not
bool
(
flags
&
os
.
O_NONBLOCK
)
if
blocking_fd
:
_map_errors
(
fcntl
.
fcntl
,
fd
,
fcntl
.
F_SETFL
,
flags
|
os
.
O_NONBLOCK
)
try
:
return
_write
(
fd
,
buf
)
except
OSError
,
e
:
if
e
.
errno
not
in
ignored_errors
:
raise
if
e
.
errno
==
EAGAIN
and
not
blocking_fd
:
raise
sys
.
exc_clear
()
finally
:
# See note in posix_read().
if
not
flags
&
os
.
O_NONBLOCK
:
if
blocking_fd
:
_map_errors
(
fcntl
.
fcntl
,
fd
,
fcntl
.
F_SETFL
,
flags
)
if
hub
is
None
:
hub
=
get_hub
()
...
...
greentest/test__os.py
View file @
576a756d
...
...
@@ -8,6 +8,11 @@ try:
except
ImportError
:
fcntl
=
None
try
:
import
errno
except
ImportError
:
errno
=
None
class
TestOS
(
TestCase
):
...
...
@@ -57,6 +62,59 @@ class TestOS(TestCase):
flags
=
fcntl
.
fcntl
(
w
,
fcntl
.
F_GETFL
,
0
)
assert
not
flags
&
os
.
O_NONBLOCK
def
test_o_nonblock_read
(
self
):
if
fcntl
is
None
or
errno
is
None
:
return
r
,
w
=
os
.
pipe
()
rflags
=
fcntl
.
fcntl
(
r
,
fcntl
.
F_GETFL
,
0
)
fcntl
.
fcntl
(
r
,
fcntl
.
F_SETFL
,
rflags
|
os
.
O_NONBLOCK
)
gotEAGAIN
=
False
try
:
os
.
read
(
r
,
3
)
except
OSError
,
e
:
if
e
.
errno
!=
errno
.
EAGAIN
:
raise
gotEAGAIN
=
True
assert
gotEAGAIN
os
.
write
(
w
,
"foo"
)
data
=
os
.
read
(
r
,
3
)
assert
data
==
"foo"
gotEAGAIN
=
False
try
:
os
.
read
(
r
,
3
)
except
OSError
,
e
:
if
e
.
errno
!=
errno
.
EAGAIN
:
raise
gotEAGAIN
=
True
assert
gotEAGAIN
def
test_o_nonblock_write
(
self
):
if
fcntl
is
None
or
errno
is
None
:
return
r
,
w
=
os
.
pipe
()
wflags
=
fcntl
.
fcntl
(
r
,
fcntl
.
F_GETFL
,
0
)
fcntl
.
fcntl
(
w
,
fcntl
.
F_SETFL
,
wflags
|
os
.
O_NONBLOCK
)
data
=
"d"
*
1000000
# fill output buffer to force EAGAIN in next os.write() call
os
.
write
(
w
,
data
)
gotEAGAIN
=
False
try
:
os
.
write
(
w
,
data
)
except
OSError
,
e
:
if
e
.
errno
!=
errno
.
EAGAIN
:
raise
gotEAGAIN
=
True
assert
gotEAGAIN
if
__name__
==
'__main__'
:
main
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment