Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
cf96dc80
Commit
cf96dc80
authored
Aug 25, 2000
by
Andrew M. Kuchling
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add interface to poll() system call (SF patch #100852)
parent
5821b777
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
319 additions
and
2 deletions
+319
-2
Modules/selectmodule.c
Modules/selectmodule.c
+319
-2
No files found.
Modules/selectmodule.c
View file @
cf96dc80
...
@@ -24,6 +24,9 @@ redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
...
@@ -24,6 +24,9 @@ redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#ifdef HAVE_LIMITS_H
#ifdef HAVE_LIMITS_H
#include <limits.h>
#include <limits.h>
#endif
#endif
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#ifdef __sgi
#ifdef __sgi
/* This is missing from unistd.h */
/* This is missing from unistd.h */
...
@@ -299,6 +302,284 @@ select_select(PyObject *self, PyObject *args)
...
@@ -299,6 +302,284 @@ select_select(PyObject *self, PyObject *args)
return
ret
;
return
ret
;
}
}
#ifdef HAVE_POLL
/*
* poll() support
*/
typedef
struct
{
PyObject_HEAD
PyObject
*
dict
;
int
ufd_uptodate
;
int
ufd_len
;
struct
pollfd
*
ufds
;
}
pollObject
;
staticforward
PyTypeObject
poll_Type
;
/* Update the malloc'ed array of pollfds to match the dictionary
contained within a pollObject. Return 1 on success, 0 on an error.
*/
static
int
update_ufd_array
(
pollObject
*
self
)
{
int
i
,
j
,
pos
;
PyObject
*
key
,
*
value
;
self
->
ufd_len
=
PyDict_Size
(
self
->
dict
);
PyMem_Resize
(
self
->
ufds
,
struct
pollfd
,
self
->
ufd_len
);
if
(
self
->
ufds
==
NULL
)
{
PyErr_NoMemory
();
return
0
;
}
i
=
pos
=
0
;
while
((
j
=
PyDict_Next
(
self
->
dict
,
&
pos
,
&
key
,
&
value
)))
{
self
->
ufds
[
i
].
fd
=
PyInt_AsLong
(
key
);
self
->
ufds
[
i
].
events
=
PyInt_AsLong
(
value
);
i
++
;
}
self
->
ufd_uptodate
=
1
;
return
1
;
}
static
char
poll_register_doc
[]
=
"register(fd [, eventmask] ) -> None
\n\n
\
Register a file descriptor with the polling object.
\n
\
fd -- either an integer, or an object with a fileno() method returning an int.
\n
\
events -- an optional bitmask describing the type of events to check for"
;
static
PyObject
*
poll_register
(
pollObject
*
self
,
PyObject
*
args
)
{
PyObject
*
o
,
*
key
,
*
value
;
int
fd
,
events
=
POLLIN
|
POLLPRI
|
POLLOUT
;
if
(
!
PyArg_ParseTuple
(
args
,
"O|i"
,
&
o
,
&
events
))
{
return
NULL
;
}
fd
=
PyObject_AsFileDescriptor
(
o
);
if
(
fd
==
-
1
)
return
NULL
;
/* Add entry to the internal dictionary: the key is the
file descriptor, and the value is the event mask. */
if
(
(
NULL
==
(
key
=
PyInt_FromLong
(
fd
)))
||
(
NULL
==
(
value
=
PyInt_FromLong
(
events
)))
||
(
PyDict_SetItem
(
self
->
dict
,
key
,
value
))
==
-
1
)
{
return
NULL
;
}
self
->
ufd_uptodate
=
0
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
char
poll_unregister_doc
[]
=
"unregister(fd) -> None
\n\n
\
Remove a file descriptor being tracked by the polling object."
;
static
PyObject
*
poll_unregister
(
pollObject
*
self
,
PyObject
*
args
)
{
PyObject
*
o
,
*
key
;
int
fd
;
if
(
!
PyArg_ParseTuple
(
args
,
"O"
,
&
o
))
{
return
NULL
;
}
fd
=
PyObject_AsFileDescriptor
(
o
);
if
(
fd
==
-
1
)
return
NULL
;
/* Check whether the fd is already in the array */
key
=
PyInt_FromLong
(
fd
);
if
(
key
==
NULL
)
return
NULL
;
if
(
PyDict_DelItem
(
self
->
dict
,
key
)
==
-
1
)
{
Py_DECREF
(
key
);
/* This will simply raise the KeyError set by PyDict_DelItem
if the file descriptor isn't registered. */
return
NULL
;
}
Py_DECREF
(
key
);
self
->
ufd_uptodate
=
0
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
char
poll_poll_doc
[]
=
"poll( [timeout] ) -> list of (fd, event) 2-tuples
\n\n
\
Polls the set of registered file descriptors, returning a list containing
\n
\
any descriptors that have events or errors to report."
;
static
PyObject
*
poll_poll
(
pollObject
*
self
,
PyObject
*
args
)
{
PyObject
*
result_list
=
NULL
,
*
tout
=
NULL
;
int
timeout
=
0
,
poll_result
,
i
,
j
;
PyObject
*
value
=
NULL
,
*
num
=
NULL
;
if
(
!
PyArg_ParseTuple
(
args
,
"|O"
,
&
tout
))
{
return
NULL
;
}
/* Check values for timeout */
if
(
tout
==
NULL
||
tout
==
Py_None
)
timeout
=
-
1
;
else
if
(
!
PyArg_Parse
(
tout
,
"i"
,
&
timeout
))
{
PyErr_SetString
(
PyExc_TypeError
,
"timeout must be an integer or None"
);
return
NULL
;
}
/* Ensure the ufd array is up to date */
if
(
!
self
->
ufd_uptodate
)
if
(
update_ufd_array
(
self
)
==
0
)
return
NULL
;
/* call poll() */
Py_BEGIN_ALLOW_THREADS
;
poll_result
=
poll
(
self
->
ufds
,
self
->
ufd_len
,
timeout
);
Py_END_ALLOW_THREADS
;
if
(
poll_result
<
0
)
{
PyErr_SetFromErrno
(
SelectError
);
return
NULL
;
}
/* build the result list */
result_list
=
PyList_New
(
poll_result
);
if
(
!
result_list
)
return
NULL
;
else
{
for
(
i
=
0
,
j
=
0
;
j
<
poll_result
;
j
++
)
{
/* skip to the next fired descriptor */
while
(
!
self
->
ufds
[
i
].
revents
)
{
i
++
;
}
/* if we hit a NULL return, set value to NULL
and break out of loop; code at end will
clean up result_list */
value
=
PyTuple_New
(
2
);
if
(
value
==
NULL
)
goto
error
;
num
=
PyInt_FromLong
(
self
->
ufds
[
i
].
fd
);
if
(
num
==
NULL
)
{
Py_DECREF
(
value
);
goto
error
;
}
PyTuple_SET_ITEM
(
value
,
0
,
num
);
num
=
PyInt_FromLong
(
self
->
ufds
[
i
].
revents
);
if
(
num
==
NULL
)
{
Py_DECREF
(
value
);
goto
error
;
}
PyTuple_SET_ITEM
(
value
,
1
,
num
);
if
((
PyList_SetItem
(
result_list
,
j
,
value
))
==
-
1
)
{
Py_DECREF
(
value
);
goto
error
;
}
i
++
;
}
}
return
result_list
;
error:
Py_DECREF
(
result_list
);
return
NULL
;
}
static
PyMethodDef
poll_methods
[]
=
{
{
"register"
,
(
PyCFunction
)
poll_register
,
METH_VARARGS
,
poll_register_doc
},
{
"unregister"
,
(
PyCFunction
)
poll_unregister
,
METH_VARARGS
,
poll_unregister_doc
},
{
"poll"
,
(
PyCFunction
)
poll_poll
,
METH_VARARGS
,
poll_poll_doc
},
{
NULL
,
NULL
}
/* sentinel */
};
static
pollObject
*
newPollObject
()
{
pollObject
*
self
;
self
=
PyObject_New
(
pollObject
,
&
poll_Type
);
if
(
self
==
NULL
)
return
NULL
;
/* ufd_uptodate is a Boolean, denoting whether the
array pointed to by ufds matches the contents of the dictionary. */
self
->
ufd_uptodate
=
0
;
self
->
ufds
=
NULL
;
self
->
dict
=
PyDict_New
();
if
(
self
->
dict
==
NULL
)
{
Py_DECREF
(
self
);
return
NULL
;
}
return
self
;
}
static
void
poll_dealloc
(
pollObject
*
self
)
{
if
(
self
->
ufds
!=
NULL
)
PyMem_DEL
(
self
->
ufds
);
Py_XDECREF
(
self
->
dict
);
PyObject_Del
(
self
);
}
static
PyObject
*
poll_getattr
(
pollObject
*
self
,
char
*
name
)
{
return
Py_FindMethod
(
poll_methods
,
(
PyObject
*
)
self
,
name
);
}
statichere
PyTypeObject
poll_Type
=
{
/* The ob_type field must be initialized in the module init function
* to be portable to Windows without using C++. */
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"poll"
,
/*tp_name*/
sizeof
(
pollObject
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
poll_dealloc
,
/*tp_dealloc*/
0
,
/*tp_print*/
(
getattrfunc
)
poll_getattr
,
/*tp_getattr*/
0
,
/*tp_setattr*/
0
,
/*tp_compare*/
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
0
,
/*tp_hash*/
};
static
char
poll_doc
[]
=
"Returns a polling object, which supports registering and
\n
\
unregistering file descriptors, and then polling them for I/O events."
;
static
PyObject
*
select_poll
(
PyObject
*
self
,
PyObject
*
args
)
{
pollObject
*
rv
;
if
(
!
PyArg_ParseTuple
(
args
,
":poll"
))
return
NULL
;
rv
=
newPollObject
();
if
(
rv
==
NULL
)
return
NULL
;
return
(
PyObject
*
)
rv
;
}
#endif
/* HAVE_POLL */
static
char
select_doc
[]
=
static
char
select_doc
[]
=
"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)
\n
\
"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)
\n
\
\n
\
\n
\
...
@@ -322,9 +603,11 @@ that are ready.\n\
...
@@ -322,9 +603,11 @@ that are ready.\n\
*** IMPORTANT NOTICE ***
\n
\
*** IMPORTANT NOTICE ***
\n
\
On Windows, only sockets are supported; on Unix, all file descriptors."
;
On Windows, only sockets are supported; on Unix, all file descriptors."
;
static
PyMethodDef
select_methods
[]
=
{
static
PyMethodDef
select_methods
[]
=
{
{
"select"
,
select_select
,
1
,
select_doc
},
{
"select"
,
select_select
,
METH_VARARGS
,
select_doc
},
#ifdef HAVE_POLL
{
"poll"
,
select_poll
,
METH_VARARGS
,
poll_doc
},
#endif
/* HAVE_POLL */
{
0
,
0
},
/* sentinel */
{
0
,
0
},
/* sentinel */
};
};
...
@@ -334,6 +617,25 @@ static char module_doc[] =
...
@@ -334,6 +617,25 @@ static char module_doc[] =
*** IMPORTANT NOTICE ***
\n
\
*** IMPORTANT NOTICE ***
\n
\
On Windows, only sockets are supported; on Unix, all file descriptors."
;
On Windows, only sockets are supported; on Unix, all file descriptors."
;
/*
* Convenience routine to export an integer value.
* For simplicity, errors (which are unlikely anyway) are ignored.
*/
static
void
insint
(
PyObject
*
d
,
char
*
name
,
int
value
)
{
PyObject
*
v
=
PyInt_FromLong
((
long
)
value
);
if
(
v
==
NULL
)
{
/* Don't bother reporting this error */
PyErr_Clear
();
}
else
{
PyDict_SetItemString
(
d
,
name
,
v
);
Py_DECREF
(
v
);
}
}
DL_EXPORT
(
void
)
DL_EXPORT
(
void
)
initselect
(
void
)
initselect
(
void
)
{
{
...
@@ -342,4 +644,19 @@ initselect(void)
...
@@ -342,4 +644,19 @@ initselect(void)
d
=
PyModule_GetDict
(
m
);
d
=
PyModule_GetDict
(
m
);
SelectError
=
PyErr_NewException
(
"select.error"
,
NULL
,
NULL
);
SelectError
=
PyErr_NewException
(
"select.error"
,
NULL
,
NULL
);
PyDict_SetItemString
(
d
,
"error"
,
SelectError
);
PyDict_SetItemString
(
d
,
"error"
,
SelectError
);
#ifdef HAVE_POLL
poll_Type
.
ob_type
=
&
PyType_Type
;
insint
(
d
,
"POLLIN"
,
POLLIN
);
insint
(
d
,
"POLLPRI"
,
POLLPRI
);
insint
(
d
,
"POLLOUT"
,
POLLOUT
);
insint
(
d
,
"POLLERR"
,
POLLERR
);
insint
(
d
,
"POLLHUP"
,
POLLHUP
);
insint
(
d
,
"POLLNVAL"
,
POLLNVAL
);
insint
(
d
,
"POLLRDNORM"
,
POLLRDNORM
);
insint
(
d
,
"POLLRDBAND"
,
POLLRDBAND
);
insint
(
d
,
"POLLWRNORM"
,
POLLWRNORM
);
insint
(
d
,
"POLLWRBAND"
,
POLLWRBAND
);
insint
(
d
,
"POLLMSG"
,
POLLMSG
);
#endif
/* HAVE_POLL */
}
}
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