This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Title: poll()/epoll() are not thread-safe
Type: crash Stage: needs patch
Components: Extension Modules Versions: Python 3.2, Python 3.3, Python 3.4, Python 2.7
Status: closed Resolution: duplicate
Dependencies: Superseder: select.poll is not thread safe
View: 8865
Assigned To: Nosy List: christian.heimes, neologix, serhiy.storchaka
Priority: normal Keywords:

Created on 2013-01-11 08:36 by neologix, last changed 2022-04-11 14:57 by admin. This issue is now closed.

File name Uploaded Description Edit neologix, 2013-01-11 08:36
Messages (3)
msg179647 - (view) Author: Charles-François Natali (neologix) * (Python committer) Date: 2013-01-11 08:36
After optimizing epoll() to use a per-instance buffer like poll() does (, I realized that it wasn't thread-safe, and can result in crashes:
 ./python /tmp/
*** glibc detected *** ./python: free(): corrupted unsorted chunks: 0x0000000001c8e690 ***
======= Backtrace: =========
======= Memory map: ========

The problem is that poll (and now epoll) array is stored per-instance, and if second call to poll() is made while another thread is currently blocked on poll(), the array is reallocated (through PyMem_Resize()) if the buffer size has changed (if the number of FDs registered has changed).

static int
update_ufd_array(pollObject *self)
    self->ufd_len = PyDict_Size(self->dict);
    PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);

can be called while another thread is blocked there:
    /* call poll() */
    poll_result = poll(self->ufds, self->ufd_len, timeout);

So when the first call to poll() returns, it can end up in SIGSEGV or heap corruption (unless the array was increased an realloc() was able to expand it in-place).

Reproducer script attached.
msg179653 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2013-01-11 08:50
For poll() see issue8865.
msg179656 - (view) Author: Charles-François Natali (neologix) * (Python committer) Date: 2013-01-11 08:58
OK, I'll close as duplicate.
Date User Action Args
2022-04-11 14:57:40adminsetgithub: 61133
2013-01-11 09:00:48neologixsetstatus: open -> closed
2013-01-11 08:58:36neologixsetsuperseder: select.poll is not thread safe
dependencies: - select.poll is not thread safe
resolution: duplicate
messages: + msg179656
2013-01-11 08:52:15serhiy.storchakasetdependencies: + select.poll is not thread safe
2013-01-11 08:50:48serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg179653
2013-01-11 08:36:44neologixcreate