Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neo
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
Kirill Smelkov
neo
Commits
4a328ade
Commit
4a328ade
authored
Aug 01, 2015
by
Julien Muchembled
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix 100% CPU usage when the closure of a connection is delayed
parent
4e739de4
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
20 additions
and
13 deletions
+20
-13
neo/lib/connection.py
neo/lib/connection.py
+5
-4
neo/lib/event.py
neo/lib/event.py
+15
-4
neo/tests/testConnection.py
neo/tests/testConnection.py
+0
-5
No files found.
neo/lib/connection.py
View file @
4a328ade
...
@@ -246,10 +246,7 @@ class BaseConnection(object):
...
@@ -246,10 +246,7 @@ class BaseConnection(object):
def
close
(
self
):
def
close
(
self
):
"""Close the connection."""
"""Close the connection."""
if
self
.
connector
is
not
None
:
if
self
.
connector
is
not
None
:
em
=
self
.
em
self
.
em
.
unregister
(
self
)
em
.
removeReader
(
self
)
em
.
removeWriter
(
self
)
em
.
unregister
(
self
)
self
.
connector
.
close
()
self
.
connector
.
close
()
self
.
connector
=
None
self
.
connector
=
None
self
.
aborted
=
False
self
.
aborted
=
False
...
@@ -538,6 +535,10 @@ class Connection(BaseConnection):
...
@@ -538,6 +535,10 @@ class Connection(BaseConnection):
global
connect_limit
global
connect_limit
t
=
time
()
t
=
time
()
if
t
<
connect_limit
:
if
t
<
connect_limit
:
# Fake _addPacket so that if does not
# try to reenable polling for writing.
self
.
write_buf
[:]
=
''
,
self
.
em
.
unregister
(
self
,
check_timeout
=
True
)
self
.
checkTimeout
=
self
.
lockWrapper
(
lambda
t
:
self
.
checkTimeout
=
self
.
lockWrapper
(
lambda
t
:
t
<
connect_limit
or
self
.
_delayed_closure
())
t
<
connect_limit
or
self
.
_delayed_closure
())
self
.
readable
=
self
.
writable
=
lambda
:
None
self
.
readable
=
self
.
writable
=
lambda
:
None
...
...
neo/lib/event.py
View file @
4a328ade
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
from
time
import
time
from
time
import
time
from
select
import
epoll
,
EPOLLIN
,
EPOLLOUT
,
EPOLLERR
,
EPOLLHUP
from
select
import
epoll
,
EPOLLIN
,
EPOLLOUT
,
EPOLLERR
,
EPOLLHUP
from
errno
import
E
INTR
,
EAGAIN
from
errno
import
E
AGAIN
,
EINTR
,
ENOENT
from
.
import
logging
from
.
import
logging
class
EpollEventManager
(
object
):
class
EpollEventManager
(
object
):
...
@@ -61,12 +61,15 @@ class EpollEventManager(object):
...
@@ -61,12 +61,15 @@ class EpollEventManager(object):
append
(
conn
)
append
(
conn
)
return
result
return
result
# epoll_wait always waits for EPOLLERR & EPOLLHUP so we're forced
# to unregister when we want to ignore all events for a connection.
def
register
(
self
,
conn
):
def
register
(
self
,
conn
):
fd
=
conn
.
getConnector
().
getDescriptor
()
fd
=
conn
.
getConnector
().
getDescriptor
()
self
.
connection_dict
[
fd
]
=
conn
self
.
connection_dict
[
fd
]
=
conn
self
.
epoll
.
register
(
fd
)
self
.
epoll
.
register
(
fd
)
def
unregister
(
self
,
conn
):
def
unregister
(
self
,
conn
,
check_timeout
=
False
):
new_pending_processing
=
[
x
for
x
in
self
.
_pending_processing
new_pending_processing
=
[
x
for
x
in
self
.
_pending_processing
if
x
is
not
conn
]
if
x
is
not
conn
]
# Check that we removed at most one entry from
# Check that we removed at most one entry from
...
@@ -74,8 +77,16 @@ class EpollEventManager(object):
...
@@ -74,8 +77,16 @@ class EpollEventManager(object):
assert
len
(
new_pending_processing
)
>
len
(
self
.
_pending_processing
)
-
2
assert
len
(
new_pending_processing
)
>
len
(
self
.
_pending_processing
)
-
2
self
.
_pending_processing
=
new_pending_processing
self
.
_pending_processing
=
new_pending_processing
fd
=
conn
.
getConnector
().
getDescriptor
()
fd
=
conn
.
getConnector
().
getDescriptor
()
self
.
epoll
.
unregister
(
fd
)
try
:
del
self
.
connection_dict
[
fd
]
self
.
epoll
.
unregister
(
fd
)
except
IOError
,
e
:
if
e
.
errno
!=
ENOENT
:
raise
else
:
self
.
reader_set
.
discard
(
fd
)
self
.
writer_set
.
discard
(
fd
)
if
not
check_timeout
:
del
self
.
connection_dict
[
fd
]
def
isIdle
(
self
):
def
isIdle
(
self
):
return
not
(
self
.
_pending_processing
or
self
.
writer_set
)
return
not
(
self
.
_pending_processing
or
self
.
writer_set
)
...
...
neo/tests/testConnection.py
View file @
4a328ade
...
@@ -395,7 +395,6 @@ class ConnectionTests(NeoUnitTestBase):
...
@@ -395,7 +395,6 @@ class ConnectionTests(NeoUnitTestBase):
self
.
_checkSend
(
1
,
"testdatasecondthird"
)
self
.
_checkSend
(
1
,
"testdatasecondthird"
)
# connection closed -> buffers flushed
# connection closed -> buffers flushed
self
.
_checkWriteBuf
(
bc
,
''
)
self
.
_checkWriteBuf
(
bc
,
''
)
self
.
_checkReaderRemoved
(
1
)
self
.
_checkConnectionClosed
(
1
)
self
.
_checkConnectionClosed
(
1
)
self
.
_checkUnregistered
(
1
)
self
.
_checkUnregistered
(
1
)
finally
:
finally
:
...
@@ -571,8 +570,6 @@ class ConnectionTests(NeoUnitTestBase):
...
@@ -571,8 +570,6 @@ class ConnectionTests(NeoUnitTestBase):
self
.
_checkUnregistered
(
1
)
self
.
_checkUnregistered
(
1
)
# nothing else pending, so writer has been removed
# nothing else pending, so writer has been removed
self
.
assertFalse
(
bc
.
pending
())
self
.
assertFalse
(
bc
.
pending
())
self
.
_checkWriterRemoved
(
1
)
self
.
_checkReaderRemoved
(
1
)
self
.
_checkClose
(
1
)
self
.
_checkClose
(
1
)
finally
:
finally
:
del
DoNothingConnector
.
send
del
DoNothingConnector
.
send
...
@@ -735,8 +732,6 @@ class ConnectionTests(NeoUnitTestBase):
...
@@ -735,8 +732,6 @@ class ConnectionTests(NeoUnitTestBase):
self
.
_checkConnectionFailed
(
0
)
self
.
_checkConnectionFailed
(
0
)
self
.
_checkUnregistered
(
1
)
self
.
_checkUnregistered
(
1
)
self
.
_checkReaderAdded
(
1
)
self
.
_checkReaderAdded
(
1
)
self
.
_checkWriterRemoved
(
1
)
self
.
_checkReaderRemoved
(
1
)
def
test_14_ServerConnection
(
self
):
def
test_14_ServerConnection
(
self
):
bc
=
self
.
_makeServerConnection
()
bc
=
self
.
_makeServerConnection
()
...
...
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