Changeset 388 for python/vendor/current/Modules/selectmodule.c
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Modules/selectmodule.c
r2 r388 25 25 #if defined(MS_WINDOWS) && !defined(FD_SETSIZE) 26 26 #define FD_SETSIZE 512 27 #endif 27 #endif 28 28 29 29 #if defined(HAVE_POLL_H) … … 48 48 49 49 #ifdef MS_WINDOWS 50 # include <winsock .h>50 # include <winsock2.h> 51 51 #else 52 52 # define SOCKET int … … 62 62 /* list of Python objects and their file descriptor */ 63 63 typedef struct { 64 PyObject *obj;/* owned reference */65 66 int sentinel;/* -1 == sentinel */64 PyObject *obj; /* owned reference */ 65 SOCKET fd; 66 int sentinel; /* -1 == sentinel */ 67 67 } pylist; 68 68 … … 70 70 reap_obj(pylist fd2obj[FD_SETSIZE + 1]) 71 71 { 72 73 74 75 76 77 72 int i; 73 for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) { 74 Py_XDECREF(fd2obj[i].obj); 75 fd2obj[i].obj = NULL; 76 } 77 fd2obj[0].sentinel = -1; 78 78 } 79 79 … … 85 85 seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1]) 86 86 { 87 int i; 88 int max = -1; 89 int index = 0; 90 int len = -1; 91 PyObject* fast_seq = NULL; 92 PyObject* o = NULL; 93 94 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */ 95 FD_ZERO(set); 96 97 fast_seq=PySequence_Fast(seq, "arguments 1-3 must be sequences"); 98 if (!fast_seq) 87 int i; 88 int max = -1; 89 int index = 0; 90 PyObject* fast_seq = NULL; 91 PyObject* o = NULL; 92 93 fd2obj[0].obj = (PyObject*)0; /* set list to zero size */ 94 FD_ZERO(set); 95 96 fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences"); 97 if (!fast_seq) 98 return -1; 99 100 for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) { 101 SOCKET v; 102 103 /* any intervening fileno() calls could decr this refcnt */ 104 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i))) 99 105 return -1; 100 106 101 len = PySequence_Fast_GET_SIZE(fast_seq); 102 103 for (i = 0; i < len; i++) { 104 SOCKET v; 105 106 /* any intervening fileno() calls could decr this refcnt */ 107 if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i))) 108 return -1; 109 110 Py_INCREF(o); 111 v = PyObject_AsFileDescriptor( o ); 112 if (v == -1) goto finally; 107 Py_INCREF(o); 108 v = PyObject_AsFileDescriptor( o ); 109 if (v == -1) goto finally; 113 110 114 111 #if defined(_MSC_VER) 115 max = 0;/* not used for Win32 */112 max = 0; /* not used for Win32 */ 116 113 #else /* !_MSC_VER */ 117 if (v < 0 || v >= FD_SETSIZE) {118 119 120 121 122 123 114 if (!_PyIsSelectable_fd(v)) { 115 PyErr_SetString(PyExc_ValueError, 116 "filedescriptor out of range in select()"); 117 goto finally; 118 } 119 if (v > max) 120 max = v; 124 121 #endif /* _MSC_VER */ 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 122 FD_SET(v, set); 123 124 /* add object and its file descriptor to the list */ 125 if (index >= FD_SETSIZE) { 126 PyErr_SetString(PyExc_ValueError, 127 "too many file descriptors in select()"); 128 goto finally; 129 } 130 fd2obj[index].obj = o; 131 fd2obj[index].fd = v; 132 fd2obj[index].sentinel = 0; 133 fd2obj[++index].sentinel = -1; 134 } 135 Py_DECREF(fast_seq); 136 return max+1; 140 137 141 138 finally: 142 143 144 139 Py_XDECREF(o); 140 Py_DECREF(fast_seq); 141 return -1; 145 142 } 146 143 … … 149 146 set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1]) 150 147 { 151 int i, j, count=0; 152 PyObject *list, *o; 153 SOCKET fd; 154 155 for (j = 0; fd2obj[j].sentinel >= 0; j++) { 156 if (FD_ISSET(fd2obj[j].fd, set)) 157 count++; 158 } 159 list = PyList_New(count); 160 if (!list) 161 return NULL; 162 163 i = 0; 164 for (j = 0; fd2obj[j].sentinel >= 0; j++) { 165 fd = fd2obj[j].fd; 166 if (FD_ISSET(fd, set)) { 167 #ifndef _MSC_VER 168 if (fd > FD_SETSIZE) { 169 PyErr_SetString(PyExc_SystemError, 170 "filedescriptor out of range returned in select()"); 171 goto finally; 172 } 173 #endif 174 o = fd2obj[j].obj; 175 fd2obj[j].obj = NULL; 176 /* transfer ownership */ 177 if (PyList_SetItem(list, i, o) < 0) 178 goto finally; 179 180 i++; 181 } 182 } 183 return list; 148 int i, j, count=0; 149 PyObject *list, *o; 150 SOCKET fd; 151 152 for (j = 0; fd2obj[j].sentinel >= 0; j++) { 153 if (FD_ISSET(fd2obj[j].fd, set)) 154 count++; 155 } 156 list = PyList_New(count); 157 if (!list) 158 return NULL; 159 160 i = 0; 161 for (j = 0; fd2obj[j].sentinel >= 0; j++) { 162 fd = fd2obj[j].fd; 163 if (FD_ISSET(fd, set)) { 164 o = fd2obj[j].obj; 165 fd2obj[j].obj = NULL; 166 /* transfer ownership */ 167 if (PyList_SetItem(list, i, o) < 0) 168 goto finally; 169 170 i++; 171 } 172 } 173 return list; 184 174 finally: 185 186 175 Py_DECREF(list); 176 return NULL; 187 177 } 188 178 … … 196 186 { 197 187 #ifdef SELECT_USES_HEAP 198 188 pylist *rfd2obj, *wfd2obj, *efd2obj; 199 189 #else /* !SELECT_USES_HEAP */ 200 201 202 203 204 205 206 207 208 190 /* XXX: All this should probably be implemented as follows: 191 * - find the highest descriptor we're interested in 192 * - add one 193 * - that's the size 194 * See: Stevens, APitUE, $12.5.1 195 */ 196 pylist rfd2obj[FD_SETSIZE + 1]; 197 pylist wfd2obj[FD_SETSIZE + 1]; 198 pylist efd2obj[FD_SETSIZE + 1]; 209 199 #endif /* SELECT_USES_HEAP */ 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 200 PyObject *ifdlist, *ofdlist, *efdlist; 201 PyObject *ret = NULL; 202 PyObject *tout = Py_None; 203 fd_set ifdset, ofdset, efdset; 204 double timeout; 205 struct timeval tv, *tvp; 206 long seconds; 207 int imax, omax, emax, max; 208 int n; 209 210 /* convert arguments */ 211 if (!PyArg_UnpackTuple(args, "select", 3, 4, 212 &ifdlist, &ofdlist, &efdlist, &tout)) 213 return NULL; 214 215 if (tout == Py_None) 216 tvp = (struct timeval *)0; 217 else if (!PyNumber_Check(tout)) { 218 PyErr_SetString(PyExc_TypeError, 219 "timeout must be a float or None"); 220 return NULL; 221 } 222 else { 223 timeout = PyFloat_AsDouble(tout); 224 if (timeout == -1 && PyErr_Occurred()) 225 return NULL; 226 if (timeout > (double)LONG_MAX) { 227 PyErr_SetString(PyExc_OverflowError, 228 "timeout period too long"); 229 return NULL; 230 } 231 seconds = (long)timeout; 232 timeout = timeout - (double)seconds; 233 tv.tv_sec = seconds; 234 tv.tv_usec = (long)(timeout * 1E6); 235 tvp = &tv; 236 } 247 237 248 238 249 239 #ifdef SELECT_USES_HEAP 250 251 252 253 254 255 256 257 258 259 240 /* Allocate memory for the lists */ 241 rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1); 242 wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1); 243 efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1); 244 if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) { 245 if (rfd2obj) PyMem_DEL(rfd2obj); 246 if (wfd2obj) PyMem_DEL(wfd2obj); 247 if (efd2obj) PyMem_DEL(efd2obj); 248 return PyErr_NoMemory(); 249 } 260 250 #endif /* SELECT_USES_HEAP */ 261 262 263 264 265 266 267 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0) 268 269 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0) 270 271 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0) 272 273 274 275 276 277 278 279 251 /* Convert sequences to fd_sets, and get maximum fd number 252 * propagates the Python exception set in seq2set() 253 */ 254 rfd2obj[0].sentinel = -1; 255 wfd2obj[0].sentinel = -1; 256 efd2obj[0].sentinel = -1; 257 if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0) 258 goto finally; 259 if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0) 260 goto finally; 261 if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0) 262 goto finally; 263 max = imax; 264 if (omax > max) max = omax; 265 if (emax > max) max = emax; 266 267 Py_BEGIN_ALLOW_THREADS 268 n = select(max, &ifdset, &ofdset, &efdset, tvp); 269 Py_END_ALLOW_THREADS 280 270 281 271 #ifdef MS_WINDOWS 282 283 284 272 if (n == SOCKET_ERROR) { 273 PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError()); 274 } 285 275 #else 286 if (n < 0) { 287 PyErr_SetFromErrno(SelectError); 288 } 289 #endif 290 else if (n == 0) { 291 /* optimization */ 292 ifdlist = PyList_New(0); 293 if (ifdlist) { 294 ret = PyTuple_Pack(3, ifdlist, ifdlist, ifdlist); 295 Py_DECREF(ifdlist); 296 } 297 } 298 else { 299 /* any of these three calls can raise an exception. it's more 300 convenient to test for this after all three calls... but 301 is that acceptable? 302 */ 303 ifdlist = set2list(&ifdset, rfd2obj); 304 ofdlist = set2list(&ofdset, wfd2obj); 305 efdlist = set2list(&efdset, efd2obj); 306 if (PyErr_Occurred()) 307 ret = NULL; 308 else 309 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist); 310 311 Py_DECREF(ifdlist); 312 Py_DECREF(ofdlist); 313 Py_DECREF(efdlist); 314 } 315 276 if (n < 0) { 277 PyErr_SetFromErrno(SelectError); 278 } 279 #endif 280 else { 281 /* any of these three calls can raise an exception. it's more 282 convenient to test for this after all three calls... but 283 is that acceptable? 284 */ 285 ifdlist = set2list(&ifdset, rfd2obj); 286 ofdlist = set2list(&ofdset, wfd2obj); 287 efdlist = set2list(&efdset, efd2obj); 288 if (PyErr_Occurred()) 289 ret = NULL; 290 else 291 ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist); 292 293 Py_DECREF(ifdlist); 294 Py_DECREF(ofdlist); 295 Py_DECREF(efdlist); 296 } 297 316 298 finally: 317 318 319 299 reap_obj(rfd2obj); 300 reap_obj(wfd2obj); 301 reap_obj(efd2obj); 320 302 #ifdef SELECT_USES_HEAP 321 322 323 303 PyMem_DEL(rfd2obj); 304 PyMem_DEL(wfd2obj); 305 PyMem_DEL(efd2obj); 324 306 #endif /* SELECT_USES_HEAP */ 325 307 return ret; 326 308 } 327 309 328 310 #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) 329 /* 311 /* 330 312 * poll() support 331 313 */ 332 314 333 315 typedef struct { 334 PyObject_HEAD 335 PyObject *dict; 336 int ufd_uptodate; 337 int ufd_len; 338 struct pollfd *ufds; 316 PyObject_HEAD 317 PyObject *dict; 318 int ufd_uptodate; 319 int ufd_len; 320 struct pollfd *ufds; 321 int poll_running; 339 322 } pollObject; 340 323 341 324 static PyTypeObject poll_Type; 342 325 343 /* Update the malloc'ed array of pollfds to match the dictionary 326 /* Update the malloc'ed array of pollfds to match the dictionary 344 327 contained within a pollObject. Return 1 on success, 0 on an error. 345 328 */ … … 348 331 update_ufd_array(pollObject *self) 349 332 { 350 Py_ssize_t i, pos; 351 PyObject *key, *value; 352 struct pollfd *old_ufds = self->ufds; 353 354 self->ufd_len = PyDict_Size(self->dict); 355 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len); 356 if (self->ufds == NULL) { 357 self->ufds = old_ufds; 358 PyErr_NoMemory(); 359 return 0; 360 } 361 362 i = pos = 0; 363 while (PyDict_Next(self->dict, &pos, &key, &value)) { 364 self->ufds[i].fd = PyInt_AsLong(key); 365 self->ufds[i].events = (short)PyInt_AsLong(value); 366 i++; 367 } 368 self->ufd_uptodate = 1; 369 return 1; 333 Py_ssize_t i, pos; 334 PyObject *key, *value; 335 struct pollfd *old_ufds = self->ufds; 336 337 self->ufd_len = PyDict_Size(self->dict); 338 PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len); 339 if (self->ufds == NULL) { 340 self->ufds = old_ufds; 341 PyErr_NoMemory(); 342 return 0; 343 } 344 345 i = pos = 0; 346 while (PyDict_Next(self->dict, &pos, &key, &value)) { 347 assert(i < self->ufd_len); 348 /* Never overflow */ 349 self->ufds[i].fd = (int)PyInt_AsLong(key); 350 self->ufds[i].events = (short)PyInt_AsLong(value); 351 i++; 352 } 353 assert(i == self->ufd_len); 354 self->ufd_uptodate = 1; 355 return 1; 370 356 } 371 357 … … 378 364 379 365 static PyObject * 380 poll_register(pollObject *self, PyObject *args) 381 { 382 PyObject *o, *key, *value; 383 int fd, events = POLLIN | POLLPRI | POLLOUT; 384 int err; 385 386 if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) { 387 return NULL; 388 } 389 390 fd = PyObject_AsFileDescriptor(o); 391 if (fd == -1) return NULL; 392 393 /* Add entry to the internal dictionary: the key is the 394 file descriptor, and the value is the event mask. */ 395 key = PyInt_FromLong(fd); 396 if (key == NULL) 397 return NULL; 398 value = PyInt_FromLong(events); 399 if (value == NULL) { 400 Py_DECREF(key); 401 return NULL; 402 } 403 err = PyDict_SetItem(self->dict, key, value); 404 Py_DECREF(key); 405 Py_DECREF(value); 406 if (err < 0) 407 return NULL; 408 409 self->ufd_uptodate = 0; 410 411 Py_INCREF(Py_None); 412 return Py_None; 366 poll_register(pollObject *self, PyObject *args) 367 { 368 PyObject *o, *key, *value; 369 int fd; 370 short events = POLLIN | POLLPRI | POLLOUT; 371 int err; 372 373 if (!PyArg_ParseTuple(args, "O|h:register", &o, &events)) { 374 return NULL; 375 } 376 377 fd = PyObject_AsFileDescriptor(o); 378 if (fd == -1) return NULL; 379 380 /* Add entry to the internal dictionary: the key is the 381 file descriptor, and the value is the event mask. */ 382 key = PyInt_FromLong(fd); 383 if (key == NULL) 384 return NULL; 385 value = PyInt_FromLong(events); 386 if (value == NULL) { 387 Py_DECREF(key); 388 return NULL; 389 } 390 err = PyDict_SetItem(self->dict, key, value); 391 Py_DECREF(key); 392 Py_DECREF(value); 393 if (err < 0) 394 return NULL; 395 396 self->ufd_uptodate = 0; 397 398 Py_INCREF(Py_None); 399 return Py_None; 413 400 } 414 401 … … 423 410 poll_modify(pollObject *self, PyObject *args) 424 411 { 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 412 PyObject *o, *key, *value; 413 int fd, events; 414 int err; 415 416 if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) { 417 return NULL; 418 } 419 420 fd = PyObject_AsFileDescriptor(o); 421 if (fd == -1) return NULL; 422 423 /* Modify registered fd */ 424 key = PyInt_FromLong(fd); 425 if (key == NULL) 426 return NULL; 427 if (PyDict_GetItem(self->dict, key) == NULL) { 428 errno = ENOENT; 429 PyErr_SetFromErrno(PyExc_IOError); 430 return NULL; 431 } 432 value = PyInt_FromLong(events); 433 if (value == NULL) { 434 Py_DECREF(key); 435 return NULL; 436 } 437 err = PyDict_SetItem(self->dict, key, value); 438 Py_DECREF(key); 439 Py_DECREF(value); 440 if (err < 0) 441 return NULL; 442 443 self->ufd_uptodate = 0; 444 445 Py_INCREF(Py_None); 446 return Py_None; 460 447 } 461 448 … … 466 453 467 454 static PyObject * 468 poll_unregister(pollObject *self, PyObject *o) 469 { 470 471 472 473 474 if (fd == -1) 475 476 477 478 479 if (key == NULL) 480 481 482 483 484 485 486 487 488 489 490 491 492 493 455 poll_unregister(pollObject *self, PyObject *o) 456 { 457 PyObject *key; 458 int fd; 459 460 fd = PyObject_AsFileDescriptor( o ); 461 if (fd == -1) 462 return NULL; 463 464 /* Check whether the fd is already in the array */ 465 key = PyInt_FromLong(fd); 466 if (key == NULL) 467 return NULL; 468 469 if (PyDict_DelItem(self->dict, key) == -1) { 470 Py_DECREF(key); 471 /* This will simply raise the KeyError set by PyDict_DelItem 472 if the file descriptor isn't registered. */ 473 return NULL; 474 } 475 476 Py_DECREF(key); 477 self->ufd_uptodate = 0; 478 479 Py_INCREF(Py_None); 480 return Py_None; 494 481 } 495 482 … … 500 487 501 488 static PyObject * 502 poll_poll(pollObject *self, PyObject *args) 503 { 504 PyObject *result_list = NULL, *tout = NULL; 505 int timeout = 0, poll_result, i, j; 506 PyObject *value = NULL, *num = NULL; 507 508 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) { 509 return NULL; 510 } 511 512 /* Check values for timeout */ 513 if (tout == NULL || tout == Py_None) 514 timeout = -1; 515 else if (!PyNumber_Check(tout)) { 516 PyErr_SetString(PyExc_TypeError, 517 "timeout must be an integer or None"); 518 return NULL; 519 } 520 else { 521 tout = PyNumber_Int(tout); 522 if (!tout) 523 return NULL; 524 timeout = PyInt_AsLong(tout); 525 Py_DECREF(tout); 526 if (timeout == -1 && PyErr_Occurred()) 527 return NULL; 528 } 529 530 /* Ensure the ufd array is up to date */ 531 if (!self->ufd_uptodate) 532 if (update_ufd_array(self) == 0) 533 return NULL; 534 535 /* call poll() */ 536 Py_BEGIN_ALLOW_THREADS 537 poll_result = poll(self->ufds, self->ufd_len, timeout); 538 Py_END_ALLOW_THREADS 539 540 if (poll_result < 0) { 541 PyErr_SetFromErrno(SelectError); 542 return NULL; 543 } 544 545 /* build the result list */ 546 547 result_list = PyList_New(poll_result); 548 if (!result_list) 549 return NULL; 550 else { 551 for (i = 0, j = 0; j < poll_result; j++) { 552 /* skip to the next fired descriptor */ 553 while (!self->ufds[i].revents) { 554 i++; 555 } 556 /* if we hit a NULL return, set value to NULL 557 and break out of loop; code at end will 558 clean up result_list */ 559 value = PyTuple_New(2); 560 if (value == NULL) 561 goto error; 562 num = PyInt_FromLong(self->ufds[i].fd); 563 if (num == NULL) { 564 Py_DECREF(value); 565 goto error; 566 } 567 PyTuple_SET_ITEM(value, 0, num); 568 569 /* The &0xffff is a workaround for AIX. 'revents' 570 is a 16-bit short, and IBM assigned POLLNVAL 571 to be 0x8000, so the conversion to int results 572 in a negative number. See SF bug #923315. */ 573 num = PyInt_FromLong(self->ufds[i].revents & 0xffff); 574 if (num == NULL) { 575 Py_DECREF(value); 576 goto error; 577 } 578 PyTuple_SET_ITEM(value, 1, num); 579 if ((PyList_SetItem(result_list, j, value)) == -1) { 580 Py_DECREF(value); 581 goto error; 582 } 583 i++; 584 } 585 } 586 return result_list; 489 poll_poll(pollObject *self, PyObject *args) 490 { 491 PyObject *result_list = NULL, *tout = NULL; 492 int timeout = 0, poll_result, i, j; 493 PyObject *value = NULL, *num = NULL; 494 495 if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) { 496 return NULL; 497 } 498 499 /* Check values for timeout */ 500 if (tout == NULL || tout == Py_None) 501 timeout = -1; 502 else if (!PyNumber_Check(tout)) { 503 PyErr_SetString(PyExc_TypeError, 504 "timeout must be an integer or None"); 505 return NULL; 506 } 507 else { 508 tout = PyNumber_Int(tout); 509 if (!tout) 510 return NULL; 511 timeout = _PyInt_AsInt(tout); 512 Py_DECREF(tout); 513 if (timeout == -1 && PyErr_Occurred()) 514 return NULL; 515 } 516 517 /* Avoid concurrent poll() invocation, issue 8865 */ 518 if (self->poll_running) { 519 PyErr_SetString(PyExc_RuntimeError, 520 "concurrent poll() invocation"); 521 return NULL; 522 } 523 524 /* Ensure the ufd array is up to date */ 525 if (!self->ufd_uptodate) 526 if (update_ufd_array(self) == 0) 527 return NULL; 528 529 self->poll_running = 1; 530 531 /* call poll() */ 532 Py_BEGIN_ALLOW_THREADS 533 poll_result = poll(self->ufds, self->ufd_len, timeout); 534 Py_END_ALLOW_THREADS 535 536 self->poll_running = 0; 537 538 if (poll_result < 0) { 539 PyErr_SetFromErrno(SelectError); 540 return NULL; 541 } 542 543 /* build the result list */ 544 545 result_list = PyList_New(poll_result); 546 if (!result_list) 547 return NULL; 548 else { 549 for (i = 0, j = 0; j < poll_result; j++) { 550 /* skip to the next fired descriptor */ 551 while (!self->ufds[i].revents) { 552 i++; 553 } 554 /* if we hit a NULL return, set value to NULL 555 and break out of loop; code at end will 556 clean up result_list */ 557 value = PyTuple_New(2); 558 if (value == NULL) 559 goto error; 560 num = PyInt_FromLong(self->ufds[i].fd); 561 if (num == NULL) { 562 Py_DECREF(value); 563 goto error; 564 } 565 PyTuple_SET_ITEM(value, 0, num); 566 567 /* The &0xffff is a workaround for AIX. 'revents' 568 is a 16-bit short, and IBM assigned POLLNVAL 569 to be 0x8000, so the conversion to int results 570 in a negative number. See SF bug #923315. */ 571 num = PyInt_FromLong(self->ufds[i].revents & 0xffff); 572 if (num == NULL) { 573 Py_DECREF(value); 574 goto error; 575 } 576 PyTuple_SET_ITEM(value, 1, num); 577 if ((PyList_SetItem(result_list, j, value)) == -1) { 578 Py_DECREF(value); 579 goto error; 580 } 581 i++; 582 } 583 } 584 return result_list; 587 585 588 586 error: 589 590 587 Py_DECREF(result_list); 588 return NULL; 591 589 } 592 590 593 591 static PyMethodDef poll_methods[] = { 594 {"register", (PyCFunction)poll_register, 595 596 {"modify",(PyCFunction)poll_modify,597 598 {"unregister",(PyCFunction)poll_unregister,599 600 {"poll", (PyCFunction)poll_poll, 601 602 {NULL, NULL}/* sentinel */592 {"register", (PyCFunction)poll_register, 593 METH_VARARGS, poll_register_doc}, 594 {"modify", (PyCFunction)poll_modify, 595 METH_VARARGS, poll_modify_doc}, 596 {"unregister", (PyCFunction)poll_unregister, 597 METH_O, poll_unregister_doc}, 598 {"poll", (PyCFunction)poll_poll, 599 METH_VARARGS, poll_poll_doc}, 600 {NULL, NULL} /* sentinel */ 603 601 }; 604 602 … … 606 604 newPollObject(void) 607 605 { 608 pollObject *self; 609 self = PyObject_New(pollObject, &poll_Type); 610 if (self == NULL) 611 return NULL; 612 /* ufd_uptodate is a Boolean, denoting whether the 613 array pointed to by ufds matches the contents of the dictionary. */ 614 self->ufd_uptodate = 0; 615 self->ufds = NULL; 616 self->dict = PyDict_New(); 617 if (self->dict == NULL) { 618 Py_DECREF(self); 619 return NULL; 620 } 621 return self; 606 pollObject *self; 607 self = PyObject_New(pollObject, &poll_Type); 608 if (self == NULL) 609 return NULL; 610 /* ufd_uptodate is a Boolean, denoting whether the 611 array pointed to by ufds matches the contents of the dictionary. */ 612 self->ufd_uptodate = 0; 613 self->ufds = NULL; 614 self->poll_running = 0; 615 self->dict = PyDict_New(); 616 if (self->dict == NULL) { 617 Py_DECREF(self); 618 return NULL; 619 } 620 return self; 622 621 } 623 622 … … 625 624 poll_dealloc(pollObject *self) 626 625 { 627 628 629 630 626 if (self->ufds != NULL) 627 PyMem_DEL(self->ufds); 628 Py_XDECREF(self->dict); 629 PyObject_Del(self); 631 630 } 632 631 … … 634 633 poll_getattr(pollObject *self, char *name) 635 634 { 636 635 return Py_FindMethod(poll_methods, (PyObject *)self, name); 637 636 } 638 637 639 638 static PyTypeObject poll_Type = { 640 641 642 643 "select.poll",/*tp_name*/644 sizeof(pollObject),/*tp_basicsize*/645 0,/*tp_itemsize*/646 647 648 0,/*tp_print*/649 650 651 0,/*tp_compare*/652 0,/*tp_repr*/653 0,/*tp_as_number*/654 0,/*tp_as_sequence*/655 0,/*tp_as_mapping*/656 0,/*tp_hash*/639 /* The ob_type field must be initialized in the module init function 640 * to be portable to Windows without using C++. */ 641 PyVarObject_HEAD_INIT(NULL, 0) 642 "select.poll", /*tp_name*/ 643 sizeof(pollObject), /*tp_basicsize*/ 644 0, /*tp_itemsize*/ 645 /* methods */ 646 (destructor)poll_dealloc, /*tp_dealloc*/ 647 0, /*tp_print*/ 648 (getattrfunc)poll_getattr, /*tp_getattr*/ 649 0, /*tp_setattr*/ 650 0, /*tp_compare*/ 651 0, /*tp_repr*/ 652 0, /*tp_as_number*/ 653 0, /*tp_as_sequence*/ 654 0, /*tp_as_mapping*/ 655 0, /*tp_hash*/ 657 656 }; 658 657 … … 664 663 select_poll(PyObject *self, PyObject *unused) 665 664 { 666 665 return (PyObject *)newPollObject(); 667 666 } 668 667 669 668 #ifdef __APPLE__ 670 /* 669 /* 671 670 * On some systems poll() sets errno on invalid file descriptors. We test 672 671 * for this at runtime because this bug may be fixed or introduced between … … 675 674 static int select_have_broken_poll(void) 676 675 { 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 676 int poll_test; 677 int filedes[2]; 678 679 struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 }; 680 681 /* Create a file descriptor to make invalid */ 682 if (pipe(filedes) < 0) { 683 return 1; 684 } 685 poll_struct.fd = filedes[0]; 686 close(filedes[0]); 687 close(filedes[1]); 688 poll_test = poll(&poll_struct, 1, 0); 689 if (poll_test < 0) { 690 return 1; 691 } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) { 692 return 1; 693 } 694 return 0; 696 695 } 697 696 #endif /* __APPLE__ */ … … 712 711 713 712 typedef struct { 714 715 SOCKET epfd;/* epoll control file descriptor */713 PyObject_HEAD 714 SOCKET epfd; /* epoll control file descriptor */ 716 715 } pyEpoll_Object; 717 716 … … 722 721 pyepoll_err_closed(void) 723 722 { 724 725 723 PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd"); 724 return NULL; 726 725 } 727 726 … … 729 728 pyepoll_internal_close(pyEpoll_Object *self) 730 729 { 731 732 733 734 735 736 737 738 739 740 730 int save_errno = 0; 731 if (self->epfd >= 0) { 732 int epfd = self->epfd; 733 self->epfd = -1; 734 Py_BEGIN_ALLOW_THREADS 735 if (close(epfd) < 0) 736 save_errno = errno; 737 Py_END_ALLOW_THREADS 738 } 739 return save_errno; 741 740 } 742 741 … … 744 743 newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd) 745 744 { 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 745 pyEpoll_Object *self; 746 747 if (sizehint == -1) { 748 sizehint = FD_SETSIZE-1; 749 } 750 else if (sizehint < 1) { 751 PyErr_Format(PyExc_ValueError, 752 "sizehint must be greater zero, got %d", 753 sizehint); 754 return NULL; 755 } 756 757 assert(type != NULL && type->tp_alloc != NULL); 758 self = (pyEpoll_Object *) type->tp_alloc(type, 0); 759 if (self == NULL) 760 return NULL; 761 762 if (fd == -1) { 763 Py_BEGIN_ALLOW_THREADS 764 self->epfd = epoll_create(sizehint); 765 Py_END_ALLOW_THREADS 766 } 767 else { 768 self->epfd = fd; 769 } 770 if (self->epfd < 0) { 771 Py_DECREF(self); 772 PyErr_SetFromErrno(PyExc_IOError); 773 return NULL; 774 } 775 return (PyObject *)self; 777 776 } 778 777 … … 781 780 pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 782 781 { 783 784 785 786 787 788 789 790 782 int sizehint = -1; 783 static char *kwlist[] = {"sizehint", NULL}; 784 785 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist, 786 &sizehint)) 787 return NULL; 788 789 return newPyEpoll_Object(type, sizehint, -1); 791 790 } 792 791 … … 795 794 pyepoll_dealloc(pyEpoll_Object *self) 796 795 { 797 798 796 (void)pyepoll_internal_close(self); 797 Py_TYPE(self)->tp_free(self); 799 798 } 800 799 … … 802 801 pyepoll_close(pyEpoll_Object *self) 803 802 { 804 805 806 807 808 809 803 errno = pyepoll_internal_close(self); 804 if (errno < 0) { 805 PyErr_SetFromErrno(PyExc_IOError); 806 return NULL; 807 } 808 Py_RETURN_NONE; 810 809 } 811 810 … … 819 818 pyepoll_get_closed(pyEpoll_Object *self) 820 819 { 821 822 823 824 820 if (self->epfd < 0) 821 Py_RETURN_TRUE; 822 else 823 Py_RETURN_FALSE; 825 824 } 826 825 … … 828 827 pyepoll_fileno(pyEpoll_Object *self) 829 828 { 830 831 832 829 if (self->epfd < 0) 830 return pyepoll_err_closed(); 831 return PyInt_FromLong(self->epfd); 833 832 } 834 833 … … 841 840 pyepoll_fromfd(PyObject *cls, PyObject *args) 842 841 { 843 844 845 846 847 848 842 SOCKET fd; 843 844 if (!PyArg_ParseTuple(args, "i:fromfd", &fd)) 845 return NULL; 846 847 return newPyEpoll_Object((PyTypeObject*)cls, -1, fd); 849 848 } 850 849 … … 857 856 pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events) 858 857 { 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 858 struct epoll_event ev; 859 int result; 860 int fd; 861 862 if (epfd < 0) 863 return pyepoll_err_closed(); 864 865 fd = PyObject_AsFileDescriptor(pfd); 866 if (fd == -1) { 867 return NULL; 868 } 869 870 switch(op) { 871 case EPOLL_CTL_ADD: 872 case EPOLL_CTL_MOD: 873 ev.events = events; 874 ev.data.fd = fd; 875 Py_BEGIN_ALLOW_THREADS 876 result = epoll_ctl(epfd, op, fd, &ev); 877 Py_END_ALLOW_THREADS 878 break; 879 case EPOLL_CTL_DEL: 880 /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL 881 * operation required a non-NULL pointer in event, even 882 * though this argument is ignored. */ 883 Py_BEGIN_ALLOW_THREADS 884 result = epoll_ctl(epfd, op, fd, &ev); 885 if (errno == EBADF) { 886 /* fd already closed */ 887 result = 0; 888 errno = 0; 889 } 890 Py_END_ALLOW_THREADS 891 break; 892 default: 893 result = -1; 894 errno = EINVAL; 895 } 896 897 if (result < 0) { 898 PyErr_SetFromErrno(PyExc_IOError); 899 return NULL; 900 } 901 Py_RETURN_NONE; 903 902 } 904 903 … … 906 905 pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds) 907 906 { 908 909 910 911 912 913 914 915 916 917 907 PyObject *pfd; 908 unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI; 909 static char *kwlist[] = {"fd", "eventmask", NULL}; 910 911 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist, 912 &pfd, &events)) { 913 return NULL; 914 } 915 916 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events); 918 917 } 919 918 920 919 PyDoc_STRVAR(pyepoll_register_doc, 921 "register(fd[, eventmask]) -> bool\n\ 922 \n\ 923 Registers a new fd or modifies an already registered fd. register() returns\n\ 924 True if a new fd was registered or False if the event mask for fd was modified.\n\ 920 "register(fd[, eventmask]) -> None\n\ 921 \n\ 922 Registers a new fd or raises an IOError if the fd is already registered.\n\ 925 923 fd is the target file descriptor of the operation.\n\ 926 924 events is a bit set composed of the various EPOLL constants; the default\n\ … … 932 930 pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds) 933 931 { 934 935 936 937 938 939 940 941 942 943 932 PyObject *pfd; 933 unsigned int events; 934 static char *kwlist[] = {"fd", "eventmask", NULL}; 935 936 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist, 937 &pfd, &events)) { 938 return NULL; 939 } 940 941 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events); 944 942 } 945 943 … … 953 951 pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds) 954 952 { 955 956 957 958 959 960 961 962 963 953 PyObject *pfd; 954 static char *kwlist[] = {"fd", NULL}; 955 956 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist, 957 &pfd)) { 958 return NULL; 959 } 960 961 return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0); 964 962 } 965 963 … … 972 970 pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds) 973 971 { 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 972 double dtimeout = -1.; 973 int timeout; 974 int maxevents = -1; 975 int nfds, i; 976 PyObject *elist = NULL, *etuple = NULL; 977 struct epoll_event *evs = NULL; 978 static char *kwlist[] = {"timeout", "maxevents", NULL}; 979 980 if (self->epfd < 0) 981 return pyepoll_err_closed(); 982 983 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist, 984 &dtimeout, &maxevents)) { 985 return NULL; 986 } 987 988 if (dtimeout < 0) { 989 timeout = -1; 990 } 991 else if (dtimeout * 1000.0 > INT_MAX) { 992 PyErr_SetString(PyExc_OverflowError, 993 "timeout is too large"); 994 return NULL; 995 } 996 else { 997 timeout = (int)(dtimeout * 1000.0); 998 } 999 1000 if (maxevents == -1) { 1001 maxevents = FD_SETSIZE-1; 1002 } 1003 else if (maxevents < 1) { 1004 PyErr_Format(PyExc_ValueError, 1005 "maxevents must be greater than 0, got %d", 1006 maxevents); 1007 return NULL; 1008 } 1009 1010 evs = PyMem_New(struct epoll_event, maxevents); 1011 if (evs == NULL) { 1012 Py_DECREF(self); 1013 PyErr_NoMemory(); 1014 return NULL; 1015 } 1016 1017 Py_BEGIN_ALLOW_THREADS 1018 nfds = epoll_wait(self->epfd, evs, maxevents, timeout); 1019 Py_END_ALLOW_THREADS 1020 if (nfds < 0) { 1021 PyErr_SetFromErrno(PyExc_IOError); 1022 goto error; 1023 } 1024 1025 elist = PyList_New(nfds); 1026 if (elist == NULL) { 1027 goto error; 1028 } 1029 1030 for (i = 0; i < nfds; i++) { 1031 etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events); 1032 if (etuple == NULL) { 1033 Py_CLEAR(elist); 1034 goto error; 1035 } 1036 PyList_SET_ITEM(elist, i, etuple); 1037 } 1040 1038 1041 1039 error: 1042 1043 1040 PyMem_Free(evs); 1041 return elist; 1044 1042 } 1045 1043 … … 1052 1050 1053 1051 static PyMethodDef pyepoll_methods[] = { 1054 {"fromfd",(PyCFunction)pyepoll_fromfd,1055 1056 {"close", (PyCFunction)pyepoll_close,METH_NOARGS,1057 1058 {"fileno", (PyCFunction)pyepoll_fileno,METH_NOARGS,1059 1060 {"modify",(PyCFunction)pyepoll_modify,1061 METH_VARARGS | METH_KEYWORDS,pyepoll_modify_doc},1062 {"register",(PyCFunction)pyepoll_register,1063 METH_VARARGS | METH_KEYWORDS,pyepoll_register_doc},1064 {"unregister",(PyCFunction)pyepoll_unregister,1065 METH_VARARGS | METH_KEYWORDS,pyepoll_unregister_doc},1066 {"poll",(PyCFunction)pyepoll_poll,1067 METH_VARARGS | METH_KEYWORDS,pyepoll_poll_doc},1068 {NULL,NULL},1052 {"fromfd", (PyCFunction)pyepoll_fromfd, 1053 METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc}, 1054 {"close", (PyCFunction)pyepoll_close, METH_NOARGS, 1055 pyepoll_close_doc}, 1056 {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS, 1057 pyepoll_fileno_doc}, 1058 {"modify", (PyCFunction)pyepoll_modify, 1059 METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc}, 1060 {"register", (PyCFunction)pyepoll_register, 1061 METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc}, 1062 {"unregister", (PyCFunction)pyepoll_unregister, 1063 METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc}, 1064 {"poll", (PyCFunction)pyepoll_poll, 1065 METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc}, 1066 {NULL, NULL}, 1069 1067 }; 1070 1068 1071 1069 static PyGetSetDef pyepoll_getsetlist[] = { 1072 1073 1074 1070 {"closed", (getter)pyepoll_get_closed, NULL, 1071 "True if the epoll handler is closed"}, 1072 {0}, 1075 1073 }; 1076 1074 … … 1085 1083 1086 1084 static PyTypeObject pyEpoll_Type = { 1087 1088 "select.epoll",/* tp_name */1089 sizeof(pyEpoll_Object),/* tp_basicsize */1090 0,/* tp_itemsize */1091 (destructor)pyepoll_dealloc,/* tp_dealloc */1092 0,/* tp_print */1093 0,/* tp_getattr */1094 0,/* tp_setattr */1095 0,/* tp_compare */1096 0,/* tp_repr */1097 0,/* tp_as_number */1098 0,/* tp_as_sequence */1099 0,/* tp_as_mapping */1100 0,/* tp_hash */1101 0,/* tp_call */1102 0,/* tp_str */1103 PyObject_GenericGetAttr,/* tp_getattro */1104 0,/* tp_setattro */1105 0,/* tp_as_buffer */1106 Py_TPFLAGS_DEFAULT,/* tp_flags */1107 pyepoll_doc,/* tp_doc */1108 0,/* tp_traverse */1109 0,/* tp_clear */1110 0,/* tp_richcompare */1111 0,/* tp_weaklistoffset */1112 0,/* tp_iter */1113 0,/* tp_iternext */1114 pyepoll_methods,/* tp_methods */1115 0,/* tp_members */1116 pyepoll_getsetlist,/* tp_getset */1117 0,/* tp_base */1118 0,/* tp_dict */1119 0,/* tp_descr_get */1120 0,/* tp_descr_set */1121 0,/* tp_dictoffset */1122 0,/* tp_init */1123 0,/* tp_alloc */1124 pyepoll_new,/* tp_new */1125 0,/* tp_free */1085 PyVarObject_HEAD_INIT(NULL, 0) 1086 "select.epoll", /* tp_name */ 1087 sizeof(pyEpoll_Object), /* tp_basicsize */ 1088 0, /* tp_itemsize */ 1089 (destructor)pyepoll_dealloc, /* tp_dealloc */ 1090 0, /* tp_print */ 1091 0, /* tp_getattr */ 1092 0, /* tp_setattr */ 1093 0, /* tp_compare */ 1094 0, /* tp_repr */ 1095 0, /* tp_as_number */ 1096 0, /* tp_as_sequence */ 1097 0, /* tp_as_mapping */ 1098 0, /* tp_hash */ 1099 0, /* tp_call */ 1100 0, /* tp_str */ 1101 PyObject_GenericGetAttr, /* tp_getattro */ 1102 0, /* tp_setattro */ 1103 0, /* tp_as_buffer */ 1104 Py_TPFLAGS_DEFAULT, /* tp_flags */ 1105 pyepoll_doc, /* tp_doc */ 1106 0, /* tp_traverse */ 1107 0, /* tp_clear */ 1108 0, /* tp_richcompare */ 1109 0, /* tp_weaklistoffset */ 1110 0, /* tp_iter */ 1111 0, /* tp_iternext */ 1112 pyepoll_methods, /* tp_methods */ 1113 0, /* tp_members */ 1114 pyepoll_getsetlist, /* tp_getset */ 1115 0, /* tp_base */ 1116 0, /* tp_dict */ 1117 0, /* tp_descr_get */ 1118 0, /* tp_descr_set */ 1119 0, /* tp_dictoffset */ 1120 0, /* tp_init */ 1121 0, /* tp_alloc */ 1122 pyepoll_new, /* tp_new */ 1123 0, /* tp_free */ 1126 1124 }; 1127 1125 … … 1162 1160 1163 1161 PyDoc_STRVAR(kqueue_event_doc, 1164 "kevent(ident, filter=KQ_FILTER_READ, flags=KQ_ ADD, fflags=0, data=0, udata=0)\n\1162 "kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\ 1165 1163 \n\ 1166 1164 This object is the equivalent of the struct kevent for the C API.\n\ … … 1178 1176 1179 1177 typedef struct { 1180 1181 1178 PyObject_HEAD 1179 struct kevent e; 1182 1180 } kqueue_event_Object; 1183 1181 … … 1187 1185 1188 1186 typedef struct { 1189 1190 SOCKET kqfd;/* kqueue control fd */1187 PyObject_HEAD 1188 SOCKET kqfd; /* kqueue control fd */ 1191 1189 } kqueue_queue_Object; 1192 1190 … … 1194 1192 1195 1193 #define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type)) 1194 1195 #if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P) 1196 # error uintptr_t does not match void *! 1197 #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG) 1198 # define T_UINTPTRT T_ULONGLONG 1199 # define T_INTPTRT T_LONGLONG 1200 # define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong 1201 # define UINTPTRT_FMT_UNIT "K" 1202 # define INTPTRT_FMT_UNIT "L" 1203 #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG) 1204 # define T_UINTPTRT T_ULONG 1205 # define T_INTPTRT T_LONG 1206 # define PyLong_AsUintptr_t PyLong_AsUnsignedLong 1207 # define UINTPTRT_FMT_UNIT "k" 1208 # define INTPTRT_FMT_UNIT "l" 1209 #elif (SIZEOF_UINTPTR_T == SIZEOF_INT) 1210 # define T_UINTPTRT T_UINT 1211 # define T_INTPTRT T_INT 1212 # define PyLong_AsUintptr_t PyLong_AsUnsignedLong 1213 # define UINTPTRT_FMT_UNIT "I" 1214 # define INTPTRT_FMT_UNIT "i" 1215 #else 1216 # error uintptr_t does not match int, long, or long long! 1217 #endif 1218 1219 /* 1220 * kevent is not standard and its members vary across BSDs. 1221 */ 1222 #if !defined(__OpenBSD__) 1223 # define IDENT_TYPE T_UINTPTRT 1224 # define IDENT_CAST Py_intptr_t 1225 # define DATA_TYPE T_INTPTRT 1226 # define DATA_FMT_UNIT INTPTRT_FMT_UNIT 1227 # define IDENT_AsType PyLong_AsUintptr_t 1228 #else 1229 # define IDENT_TYPE T_UINT 1230 # define IDENT_CAST int 1231 # define DATA_TYPE T_INT 1232 # define DATA_FMT_UNIT "i" 1233 # define IDENT_AsType PyLong_AsUnsignedLong 1234 #endif 1196 1235 1197 1236 /* Unfortunately, we can't store python objects in udata, because … … 1202 1241 #define KQ_OFF(x) offsetof(kqueue_event_Object, x) 1203 1242 static struct PyMemberDef kqueue_event_members[] = { 1204 {"ident", T_UINT,KQ_OFF(e.ident)},1205 {"filter", T_SHORT,KQ_OFF(e.filter)},1206 {"flags", T_USHORT,KQ_OFF(e.flags)},1207 {"fflags", T_UINT,KQ_OFF(e.fflags)},1208 {"data", T_INT,KQ_OFF(e.data)},1209 {"udata", T_INT,KQ_OFF(e.udata)},1210 1243 {"ident", IDENT_TYPE, KQ_OFF(e.ident)}, 1244 {"filter", T_SHORT, KQ_OFF(e.filter)}, 1245 {"flags", T_USHORT, KQ_OFF(e.flags)}, 1246 {"fflags", T_UINT, KQ_OFF(e.fflags)}, 1247 {"data", DATA_TYPE, KQ_OFF(e.data)}, 1248 {"udata", T_UINTPTRT, KQ_OFF(e.udata)}, 1249 {NULL} /* Sentinel */ 1211 1250 }; 1212 1251 #undef KQ_OFF 1213 1252 1214 1253 static PyObject * 1254 1215 1255 kqueue_event_repr(kqueue_event_Object *s) 1216 1256 { 1217 1218 1219 1220 "<select.kevent ident=%lu filter=%d flags=0x%x fflags=0x%x "1221 "data=0x%lxudata=%p>",1222 (unsigned long)(s->e.ident), s->e.filter, s->e.flags,1223 s->e.fflags, (long)(s->e.data), s->e.udata);1224 1257 char buf[1024]; 1258 PyOS_snprintf( 1259 buf, sizeof(buf), 1260 "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x " 1261 "data=0x%zd udata=%p>", 1262 (size_t)(s->e.ident), s->e.filter, s->e.flags, 1263 s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata); 1264 return PyString_FromString(buf); 1225 1265 } 1226 1266 … … 1228 1268 kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds) 1229 1269 { 1230 PyObject *pfd; 1231 static char *kwlist[] = {"ident", "filter", "flags", "fflags", 1232 "data", "udata", NULL}; 1233 1234 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */ 1235 1236 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|hhiii:kevent", kwlist, 1237 &pfd, &(self->e.filter), &(self->e.flags), 1238 &(self->e.fflags), &(self->e.data), &(self->e.udata))) { 1239 return -1; 1240 } 1241 1242 self->e.ident = PyObject_AsFileDescriptor(pfd); 1243 if (self->e.ident == -1) { 1244 return -1; 1245 } 1246 return 0; 1270 PyObject *pfd; 1271 static char *kwlist[] = {"ident", "filter", "flags", "fflags", 1272 "data", "udata", NULL}; 1273 static char *fmt = "O|hHI" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent"; 1274 1275 EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */ 1276 1277 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist, 1278 &pfd, &(self->e.filter), &(self->e.flags), 1279 &(self->e.fflags), &(self->e.data), &(self->e.udata))) { 1280 return -1; 1281 } 1282 1283 if (PyLong_Check(pfd) 1284 #if IDENT_TYPE == T_UINT 1285 && PyLong_AsUnsignedLong(pfd) <= UINT_MAX 1286 #endif 1287 ) { 1288 self->e.ident = IDENT_AsType(pfd); 1289 } 1290 else { 1291 self->e.ident = PyObject_AsFileDescriptor(pfd); 1292 } 1293 if (PyErr_Occurred()) { 1294 return -1; 1295 } 1296 return 0; 1247 1297 } 1248 1298 1249 1299 static PyObject * 1250 1300 kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o, 1251 1252 { 1253 int result = 0;1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 if (((result = s->e.ident - o->e.ident) == 0) &&1267 1268 1269 ((result = s->e.fflags - o->e.fflags) == 0) &&1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 return PyBool_FromLong(result);1301 int op) 1302 { 1303 Py_intptr_t result = 0; 1304 1305 if (!kqueue_event_Check(o)) { 1306 if (op == Py_EQ || op == Py_NE) { 1307 PyObject *res = op == Py_EQ ? Py_False : Py_True; 1308 Py_INCREF(res); 1309 return res; 1310 } 1311 PyErr_Format(PyExc_TypeError, 1312 "can't compare %.200s to %.200s", 1313 Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name); 1314 return NULL; 1315 } 1316 if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) && 1317 ((result = s->e.filter - o->e.filter) == 0) && 1318 ((result = s->e.flags - o->e.flags) == 0) && 1319 ((result = (int)(s->e.fflags - o->e.fflags)) == 0) && 1320 ((result = s->e.data - o->e.data) == 0) && 1321 ((result = s->e.udata - o->e.udata) == 0) 1322 ) { 1323 result = 0; 1324 } 1325 1326 switch (op) { 1327 case Py_EQ: 1328 result = (result == 0); 1329 break; 1330 case Py_NE: 1331 result = (result != 0); 1332 break; 1333 case Py_LE: 1334 result = (result <= 0); 1335 break; 1336 case Py_GE: 1337 result = (result >= 0); 1338 break; 1339 case Py_LT: 1340 result = (result < 0); 1341 break; 1342 case Py_GT: 1343 result = (result > 0); 1344 break; 1345 } 1346 return PyBool_FromLong((long)result); 1297 1347 } 1298 1348 1299 1349 static PyTypeObject kqueue_event_Type = { 1300 1301 "select.kevent",/* tp_name */1302 sizeof(kqueue_event_Object),/* tp_basicsize */1303 0,/* tp_itemsize */1304 0,/* tp_dealloc */1305 0,/* tp_print */1306 0,/* tp_getattr */1307 0,/* tp_setattr */1308 0,/* tp_compare */1309 (reprfunc)kqueue_event_repr,/* tp_repr */1310 0,/* tp_as_number */1311 0,/* tp_as_sequence */1312 0,/* tp_as_mapping */1313 0,/* tp_hash */1314 0,/* tp_call */1315 0,/* tp_str */1316 0,/* tp_getattro */1317 0,/* tp_setattro */1318 0,/* tp_as_buffer */1319 Py_TPFLAGS_DEFAULT,/* tp_flags */1320 kqueue_event_doc,/* tp_doc */1321 0,/* tp_traverse */1322 0,/* tp_clear */1323 (richcmpfunc)kqueue_event_richcompare,/* tp_richcompare */1324 0,/* tp_weaklistoffset */1325 0,/* tp_iter */1326 0,/* tp_iternext */1327 0,/* tp_methods */1328 kqueue_event_members,/* tp_members */1329 0,/* tp_getset */1330 0,/* tp_base */1331 0,/* tp_dict */1332 0,/* tp_descr_get */1333 0,/* tp_descr_set */1334 0,/* tp_dictoffset */1335 (initproc)kqueue_event_init,/* tp_init */1336 0,/* tp_alloc */1337 0,/* tp_new */1338 0,/* tp_free */1350 PyVarObject_HEAD_INIT(NULL, 0) 1351 "select.kevent", /* tp_name */ 1352 sizeof(kqueue_event_Object), /* tp_basicsize */ 1353 0, /* tp_itemsize */ 1354 0, /* tp_dealloc */ 1355 0, /* tp_print */ 1356 0, /* tp_getattr */ 1357 0, /* tp_setattr */ 1358 0, /* tp_compare */ 1359 (reprfunc)kqueue_event_repr, /* tp_repr */ 1360 0, /* tp_as_number */ 1361 0, /* tp_as_sequence */ 1362 0, /* tp_as_mapping */ 1363 0, /* tp_hash */ 1364 0, /* tp_call */ 1365 0, /* tp_str */ 1366 0, /* tp_getattro */ 1367 0, /* tp_setattro */ 1368 0, /* tp_as_buffer */ 1369 Py_TPFLAGS_DEFAULT, /* tp_flags */ 1370 kqueue_event_doc, /* tp_doc */ 1371 0, /* tp_traverse */ 1372 0, /* tp_clear */ 1373 (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */ 1374 0, /* tp_weaklistoffset */ 1375 0, /* tp_iter */ 1376 0, /* tp_iternext */ 1377 0, /* tp_methods */ 1378 kqueue_event_members, /* tp_members */ 1379 0, /* tp_getset */ 1380 0, /* tp_base */ 1381 0, /* tp_dict */ 1382 0, /* tp_descr_get */ 1383 0, /* tp_descr_set */ 1384 0, /* tp_dictoffset */ 1385 (initproc)kqueue_event_init, /* tp_init */ 1386 0, /* tp_alloc */ 1387 0, /* tp_new */ 1388 0, /* tp_free */ 1339 1389 }; 1340 1390 … … 1342 1392 kqueue_queue_err_closed(void) 1343 1393 { 1344 1345 1394 PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd"); 1395 return NULL; 1346 1396 } 1347 1397 … … 1349 1399 kqueue_queue_internal_close(kqueue_queue_Object *self) 1350 1400 { 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1401 int save_errno = 0; 1402 if (self->kqfd >= 0) { 1403 int kqfd = self->kqfd; 1404 self->kqfd = -1; 1405 Py_BEGIN_ALLOW_THREADS 1406 if (close(kqfd) < 0) 1407 save_errno = errno; 1408 Py_END_ALLOW_THREADS 1409 } 1410 return save_errno; 1361 1411 } 1362 1412 … … 1364 1414 newKqueue_Object(PyTypeObject *type, SOCKET fd) 1365 1415 { 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1416 kqueue_queue_Object *self; 1417 assert(type != NULL && type->tp_alloc != NULL); 1418 self = (kqueue_queue_Object *) type->tp_alloc(type, 0); 1419 if (self == NULL) { 1420 return NULL; 1421 } 1422 1423 if (fd == -1) { 1424 Py_BEGIN_ALLOW_THREADS 1425 self->kqfd = kqueue(); 1426 Py_END_ALLOW_THREADS 1427 } 1428 else { 1429 self->kqfd = fd; 1430 } 1431 if (self->kqfd < 0) { 1432 Py_DECREF(self); 1433 PyErr_SetFromErrno(PyExc_IOError); 1434 return NULL; 1435 } 1436 return (PyObject *)self; 1387 1437 } 1388 1438 … … 1391 1441 { 1392 1442 1393 1394 1395 1396 1397 1398 1399 1400 1443 if ((args != NULL && PyObject_Size(args)) || 1444 (kwds != NULL && PyObject_Size(kwds))) { 1445 PyErr_SetString(PyExc_ValueError, 1446 "select.kqueue doesn't accept arguments"); 1447 return NULL; 1448 } 1449 1450 return newKqueue_Object(type, -1); 1401 1451 } 1402 1452 … … 1404 1454 kqueue_queue_dealloc(kqueue_queue_Object *self) 1405 1455 { 1406 1407 1456 kqueue_queue_internal_close(self); 1457 Py_TYPE(self)->tp_free(self); 1408 1458 } 1409 1459 … … 1411 1461 kqueue_queue_close(kqueue_queue_Object *self) 1412 1462 { 1413 1414 1415 1416 1417 1418 1463 errno = kqueue_queue_internal_close(self); 1464 if (errno < 0) { 1465 PyErr_SetFromErrno(PyExc_IOError); 1466 return NULL; 1467 } 1468 Py_RETURN_NONE; 1419 1469 } 1420 1470 … … 1428 1478 kqueue_queue_get_closed(kqueue_queue_Object *self) 1429 1479 { 1430 1431 1432 1433 1480 if (self->kqfd < 0) 1481 Py_RETURN_TRUE; 1482 else 1483 Py_RETURN_FALSE; 1434 1484 } 1435 1485 … … 1437 1487 kqueue_queue_fileno(kqueue_queue_Object *self) 1438 1488 { 1439 1440 1441 1489 if (self->kqfd < 0) 1490 return kqueue_queue_err_closed(); 1491 return PyInt_FromLong(self->kqfd); 1442 1492 } 1443 1493 … … 1450 1500 kqueue_queue_fromfd(PyObject *cls, PyObject *args) 1451 1501 { 1452 1453 1454 1455 1456 1457 1502 SOCKET fd; 1503 1504 if (!PyArg_ParseTuple(args, "i:fromfd", &fd)) 1505 return NULL; 1506 1507 return newKqueue_Object((PyTypeObject*)cls, fd); 1458 1508 } 1459 1509 … … 1466 1516 kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) 1467 1517 { 1468 int nevents = 0; 1469 int gotevents = 0; 1470 int nchanges = 0; 1471 int i = 0; 1472 PyObject *otimeout = NULL; 1473 PyObject *ch = NULL; 1474 PyObject *it = NULL, *ei = NULL; 1475 PyObject *result = NULL; 1476 struct kevent *evl = NULL; 1477 struct kevent *chl = NULL; 1478 struct timespec timeoutspec; 1479 struct timespec *ptimeoutspec; 1480 1481 if (self->kqfd < 0) 1482 return kqueue_queue_err_closed(); 1483 1484 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout)) 1485 return NULL; 1486 1487 if (nevents < 0) { 1488 PyErr_Format(PyExc_ValueError, 1489 "Length of eventlist must be 0 or positive, got %d", 1490 nevents); 1491 return NULL; 1492 } 1493 1494 if (ch != NULL && ch != Py_None) { 1495 it = PyObject_GetIter(ch); 1496 if (it == NULL) { 1497 PyErr_SetString(PyExc_TypeError, 1498 "changelist is not iterable"); 1499 return NULL; 1500 } 1501 nchanges = PyObject_Size(ch); 1502 if (nchanges < 0) { 1503 return NULL; 1504 } 1505 } 1506 1507 if (otimeout == Py_None || otimeout == NULL) { 1508 ptimeoutspec = NULL; 1509 } 1510 else if (PyNumber_Check(otimeout)) { 1511 double timeout; 1512 long seconds; 1513 1514 timeout = PyFloat_AsDouble(otimeout); 1515 if (timeout == -1 && PyErr_Occurred()) 1516 return NULL; 1517 if (timeout > (double)LONG_MAX) { 1518 PyErr_SetString(PyExc_OverflowError, 1519 "timeout period too long"); 1520 return NULL; 1521 } 1522 if (timeout < 0) { 1523 PyErr_SetString(PyExc_ValueError, 1524 "timeout must be positive or None"); 1525 return NULL; 1526 } 1527 1528 seconds = (long)timeout; 1529 timeout = timeout - (double)seconds; 1530 timeoutspec.tv_sec = seconds; 1531 timeoutspec.tv_nsec = (long)(timeout * 1E9); 1532 ptimeoutspec = &timeoutspec; 1533 } 1534 else { 1535 PyErr_Format(PyExc_TypeError, 1536 "timeout argument must be an number " 1537 "or None, got %.200s", 1538 Py_TYPE(otimeout)->tp_name); 1539 return NULL; 1540 } 1541 1542 if (nchanges) { 1543 chl = PyMem_New(struct kevent, nchanges); 1544 if (chl == NULL) { 1545 PyErr_NoMemory(); 1546 return NULL; 1547 } 1548 i = 0; 1549 while ((ei = PyIter_Next(it)) != NULL) { 1550 if (!kqueue_event_Check(ei)) { 1551 Py_DECREF(ei); 1552 PyErr_SetString(PyExc_TypeError, 1553 "changelist must be an iterable of " 1554 "select.kevent objects"); 1555 goto error; 1556 } else { 1557 chl[i++] = ((kqueue_event_Object *)ei)->e; 1558 } 1559 Py_DECREF(ei); 1560 } 1561 } 1562 Py_CLEAR(it); 1563 1564 /* event list */ 1565 if (nevents) { 1566 evl = PyMem_New(struct kevent, nevents); 1567 if (evl == NULL) { 1568 PyErr_NoMemory(); 1569 return NULL; 1570 } 1571 } 1572 1573 Py_BEGIN_ALLOW_THREADS 1574 gotevents = kevent(self->kqfd, chl, nchanges, 1575 evl, nevents, ptimeoutspec); 1576 Py_END_ALLOW_THREADS 1577 1578 if (gotevents == -1) { 1579 PyErr_SetFromErrno(PyExc_OSError); 1580 goto error; 1581 } 1582 1583 result = PyList_New(gotevents); 1584 if (result == NULL) { 1585 goto error; 1586 } 1587 1588 for (i = 0; i < gotevents; i++) { 1589 kqueue_event_Object *ch; 1590 1591 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type); 1592 if (ch == NULL) { 1593 goto error; 1594 } 1595 ch->e = evl[i]; 1596 PyList_SET_ITEM(result, i, (PyObject *)ch); 1597 } 1598 PyMem_Free(chl); 1599 PyMem_Free(evl); 1600 return result; 1518 int nevents = 0; 1519 int gotevents = 0; 1520 int nchanges = 0; 1521 int i = 0; 1522 PyObject *otimeout = NULL; 1523 PyObject *ch = NULL; 1524 PyObject *it = NULL, *ei = NULL; 1525 PyObject *result = NULL; 1526 struct kevent *evl = NULL; 1527 struct kevent *chl = NULL; 1528 struct timespec timeoutspec; 1529 struct timespec *ptimeoutspec; 1530 1531 if (self->kqfd < 0) 1532 return kqueue_queue_err_closed(); 1533 1534 if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout)) 1535 return NULL; 1536 1537 if (nevents < 0) { 1538 PyErr_Format(PyExc_ValueError, 1539 "Length of eventlist must be 0 or positive, got %d", 1540 nevents); 1541 return NULL; 1542 } 1543 1544 if (otimeout == Py_None || otimeout == NULL) { 1545 ptimeoutspec = NULL; 1546 } 1547 else if (PyNumber_Check(otimeout)) { 1548 double timeout; 1549 long seconds; 1550 1551 timeout = PyFloat_AsDouble(otimeout); 1552 if (timeout == -1 && PyErr_Occurred()) 1553 return NULL; 1554 if (timeout > (double)LONG_MAX) { 1555 PyErr_SetString(PyExc_OverflowError, 1556 "timeout period too long"); 1557 return NULL; 1558 } 1559 if (timeout < 0) { 1560 PyErr_SetString(PyExc_ValueError, 1561 "timeout must be positive or None"); 1562 return NULL; 1563 } 1564 1565 seconds = (long)timeout; 1566 timeout = timeout - (double)seconds; 1567 timeoutspec.tv_sec = seconds; 1568 timeoutspec.tv_nsec = (long)(timeout * 1E9); 1569 ptimeoutspec = &timeoutspec; 1570 } 1571 else { 1572 PyErr_Format(PyExc_TypeError, 1573 "timeout argument must be an number " 1574 "or None, got %.200s", 1575 Py_TYPE(otimeout)->tp_name); 1576 return NULL; 1577 } 1578 1579 if (ch != NULL && ch != Py_None) { 1580 it = PyObject_GetIter(ch); 1581 if (it == NULL) { 1582 PyErr_SetString(PyExc_TypeError, 1583 "changelist is not iterable"); 1584 return NULL; 1585 } 1586 nchanges = PyObject_Size(ch); 1587 if (nchanges < 0) { 1588 goto error; 1589 } 1590 1591 chl = PyMem_New(struct kevent, nchanges); 1592 if (chl == NULL) { 1593 PyErr_NoMemory(); 1594 goto error; 1595 } 1596 i = 0; 1597 while ((ei = PyIter_Next(it)) != NULL) { 1598 if (!kqueue_event_Check(ei)) { 1599 Py_DECREF(ei); 1600 PyErr_SetString(PyExc_TypeError, 1601 "changelist must be an iterable of " 1602 "select.kevent objects"); 1603 goto error; 1604 } else { 1605 chl[i++] = ((kqueue_event_Object *)ei)->e; 1606 } 1607 Py_DECREF(ei); 1608 } 1609 } 1610 Py_CLEAR(it); 1611 1612 /* event list */ 1613 if (nevents) { 1614 evl = PyMem_New(struct kevent, nevents); 1615 if (evl == NULL) { 1616 PyErr_NoMemory(); 1617 goto error; 1618 } 1619 } 1620 1621 Py_BEGIN_ALLOW_THREADS 1622 gotevents = kevent(self->kqfd, chl, nchanges, 1623 evl, nevents, ptimeoutspec); 1624 Py_END_ALLOW_THREADS 1625 1626 if (gotevents == -1) { 1627 PyErr_SetFromErrno(PyExc_OSError); 1628 goto error; 1629 } 1630 1631 result = PyList_New(gotevents); 1632 if (result == NULL) { 1633 goto error; 1634 } 1635 1636 for (i = 0; i < gotevents; i++) { 1637 kqueue_event_Object *ch; 1638 1639 ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type); 1640 if (ch == NULL) { 1641 goto error; 1642 } 1643 ch->e = evl[i]; 1644 PyList_SET_ITEM(result, i, (PyObject *)ch); 1645 } 1646 PyMem_Free(chl); 1647 PyMem_Free(evl); 1648 return result; 1601 1649 1602 1650 error: 1603 1604 1605 1606 1607 1651 PyMem_Free(chl); 1652 PyMem_Free(evl); 1653 Py_XDECREF(result); 1654 Py_XDECREF(it); 1655 return NULL; 1608 1656 } 1609 1657 … … 1621 1669 1622 1670 static PyMethodDef kqueue_queue_methods[] = { 1623 {"fromfd",(PyCFunction)kqueue_queue_fromfd,1624 1625 {"close", (PyCFunction)kqueue_queue_close,METH_NOARGS,1626 1627 {"fileno", (PyCFunction)kqueue_queue_fileno,METH_NOARGS,1628 1629 {"control",(PyCFunction)kqueue_queue_control,1630 METH_VARARGS ,kqueue_queue_control_doc},1631 {NULL,NULL},1671 {"fromfd", (PyCFunction)kqueue_queue_fromfd, 1672 METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc}, 1673 {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS, 1674 kqueue_queue_close_doc}, 1675 {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS, 1676 kqueue_queue_fileno_doc}, 1677 {"control", (PyCFunction)kqueue_queue_control, 1678 METH_VARARGS , kqueue_queue_control_doc}, 1679 {NULL, NULL}, 1632 1680 }; 1633 1681 1634 1682 static PyGetSetDef kqueue_queue_getsetlist[] = { 1635 1636 1637 1683 {"closed", (getter)kqueue_queue_get_closed, NULL, 1684 "True if the kqueue handler is closed"}, 1685 {0}, 1638 1686 }; 1639 1687 … … 1654 1702 1655 1703 static PyTypeObject kqueue_queue_Type = { 1656 1657 "select.kqueue",/* tp_name */1658 sizeof(kqueue_queue_Object),/* tp_basicsize */1659 0,/* tp_itemsize */1660 (destructor)kqueue_queue_dealloc,/* tp_dealloc */1661 0,/* tp_print */1662 0,/* tp_getattr */1663 0,/* tp_setattr */1664 0,/* tp_compare */1665 0,/* tp_repr */1666 0,/* tp_as_number */1667 0,/* tp_as_sequence */1668 0,/* tp_as_mapping */1669 0,/* tp_hash */1670 0,/* tp_call */1671 0,/* tp_str */1672 0,/* tp_getattro */1673 0,/* tp_setattro */1674 0,/* tp_as_buffer */1675 Py_TPFLAGS_DEFAULT,/* tp_flags */1676 kqueue_queue_doc,/* tp_doc */1677 0,/* tp_traverse */1678 0,/* tp_clear */1679 0,/* tp_richcompare */1680 0,/* tp_weaklistoffset */1681 0,/* tp_iter */1682 0,/* tp_iternext */1683 kqueue_queue_methods,/* tp_methods */1684 0,/* tp_members */1685 kqueue_queue_getsetlist,/* tp_getset */1686 0,/* tp_base */1687 0,/* tp_dict */1688 0,/* tp_descr_get */1689 0,/* tp_descr_set */1690 0,/* tp_dictoffset */1691 0,/* tp_init */1692 0,/* tp_alloc */1693 kqueue_queue_new,/* tp_new */1694 0,/* tp_free */1704 PyVarObject_HEAD_INIT(NULL, 0) 1705 "select.kqueue", /* tp_name */ 1706 sizeof(kqueue_queue_Object), /* tp_basicsize */ 1707 0, /* tp_itemsize */ 1708 (destructor)kqueue_queue_dealloc, /* tp_dealloc */ 1709 0, /* tp_print */ 1710 0, /* tp_getattr */ 1711 0, /* tp_setattr */ 1712 0, /* tp_compare */ 1713 0, /* tp_repr */ 1714 0, /* tp_as_number */ 1715 0, /* tp_as_sequence */ 1716 0, /* tp_as_mapping */ 1717 0, /* tp_hash */ 1718 0, /* tp_call */ 1719 0, /* tp_str */ 1720 0, /* tp_getattro */ 1721 0, /* tp_setattro */ 1722 0, /* tp_as_buffer */ 1723 Py_TPFLAGS_DEFAULT, /* tp_flags */ 1724 kqueue_queue_doc, /* tp_doc */ 1725 0, /* tp_traverse */ 1726 0, /* tp_clear */ 1727 0, /* tp_richcompare */ 1728 0, /* tp_weaklistoffset */ 1729 0, /* tp_iter */ 1730 0, /* tp_iternext */ 1731 kqueue_queue_methods, /* tp_methods */ 1732 0, /* tp_members */ 1733 kqueue_queue_getsetlist, /* tp_getset */ 1734 0, /* tp_base */ 1735 0, /* tp_dict */ 1736 0, /* tp_descr_get */ 1737 0, /* tp_descr_set */ 1738 0, /* tp_dictoffset */ 1739 0, /* tp_init */ 1740 0, /* tp_alloc */ 1741 kqueue_queue_new, /* tp_new */ 1742 0, /* tp_free */ 1695 1743 }; 1696 1744 … … 1723 1771 1724 1772 static PyMethodDef select_methods[] = { 1725 {"select", select_select, METH_VARARGS,select_doc},1726 #if def HAVE_POLL1727 {"poll", select_poll, METH_NOARGS,poll_doc},1773 {"select", select_select, METH_VARARGS, select_doc}, 1774 #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) 1775 {"poll", select_poll, METH_NOARGS, poll_doc}, 1728 1776 #endif /* HAVE_POLL */ 1729 {0, 0},/* sentinel */1777 {0, 0}, /* sentinel */ 1730 1778 }; 1731 1779 … … 1739 1787 initselect(void) 1740 1788 { 1741 PyObject *m; 1742 m = Py_InitModule3("select", select_methods, module_doc); 1743 if (m == NULL) 1744 return; 1745 1746 SelectError = PyErr_NewException("select.error", NULL, NULL); 1747 Py_INCREF(SelectError); 1748 PyModule_AddObject(m, "error", SelectError); 1749 1750 #if defined(HAVE_POLL) 1789 PyObject *m; 1790 m = Py_InitModule3("select", select_methods, module_doc); 1791 if (m == NULL) 1792 return; 1793 1794 SelectError = PyErr_NewException("select.error", NULL, NULL); 1795 Py_INCREF(SelectError); 1796 PyModule_AddObject(m, "error", SelectError); 1797 1798 #ifdef PIPE_BUF 1799 #ifdef HAVE_BROKEN_PIPE_BUF 1800 #undef PIPE_BUF 1801 #define PIPE_BUF 512 1802 #endif 1803 PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF); 1804 #endif 1805 1806 #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) 1751 1807 #ifdef __APPLE__ 1752 1753 1754 1755 1756 1808 if (select_have_broken_poll()) { 1809 if (PyObject_DelAttrString(m, "poll") == -1) { 1810 PyErr_Clear(); 1811 } 1812 } else { 1757 1813 #else 1758 1759 #endif 1760 1761 1762 1763 1764 1765 1766 1814 { 1815 #endif 1816 Py_TYPE(&poll_Type) = &PyType_Type; 1817 PyModule_AddIntConstant(m, "POLLIN", POLLIN); 1818 PyModule_AddIntConstant(m, "POLLPRI", POLLPRI); 1819 PyModule_AddIntConstant(m, "POLLOUT", POLLOUT); 1820 PyModule_AddIntConstant(m, "POLLERR", POLLERR); 1821 PyModule_AddIntConstant(m, "POLLHUP", POLLHUP); 1822 PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL); 1767 1823 1768 1824 #ifdef POLLRDNORM 1769 1825 PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM); 1770 1826 #endif 1771 1827 #ifdef POLLRDBAND 1772 1828 PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND); 1773 1829 #endif 1774 1830 #ifdef POLLWRNORM 1775 1831 PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM); 1776 1832 #endif 1777 1833 #ifdef POLLWRBAND 1778 1834 PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND); 1779 1835 #endif 1780 1836 #ifdef POLLMSG 1781 1782 #endif 1783 1837 PyModule_AddIntConstant(m, "POLLMSG", POLLMSG); 1838 #endif 1839 } 1784 1840 #endif /* HAVE_POLL */ 1785 1841 1786 1842 #ifdef HAVE_EPOLL 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1843 Py_TYPE(&pyEpoll_Type) = &PyType_Type; 1844 if (PyType_Ready(&pyEpoll_Type) < 0) 1845 return; 1846 1847 Py_INCREF(&pyEpoll_Type); 1848 PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type); 1849 1850 PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN); 1851 PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT); 1852 PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI); 1853 PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR); 1854 PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP); 1855 PyModule_AddIntConstant(m, "EPOLLET", EPOLLET); 1800 1856 #ifdef EPOLLONESHOT 1801 1802 1803 #endif 1804 1805 1806 1807 1808 1809 1857 /* Kernel 2.6.2+ */ 1858 PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT); 1859 #endif 1860 /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */ 1861 PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM); 1862 PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND); 1863 PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM); 1864 PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND); 1865 PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG); 1810 1866 #endif /* HAVE_EPOLL */ 1811 1867 1812 1868 #ifdef HAVE_KQUEUE 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1869 kqueue_event_Type.tp_new = PyType_GenericNew; 1870 Py_TYPE(&kqueue_event_Type) = &PyType_Type; 1871 if(PyType_Ready(&kqueue_event_Type) < 0) 1872 return; 1873 1874 Py_INCREF(&kqueue_event_Type); 1875 PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type); 1876 1877 Py_TYPE(&kqueue_queue_Type) = &PyType_Type; 1878 if(PyType_Ready(&kqueue_queue_Type) < 0) 1879 return; 1880 Py_INCREF(&kqueue_queue_Type); 1881 PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type); 1882 1883 /* event filters */ 1884 PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ); 1885 PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE); 1886 PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO); 1887 PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE); 1888 PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC); 1833 1889 #ifdef EVFILT_NETDEV 1834 1835 #endif 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1890 PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV); 1891 #endif 1892 PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL); 1893 PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER); 1894 1895 /* event flags */ 1896 PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD); 1897 PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE); 1898 PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE); 1899 PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE); 1900 PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT); 1901 PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR); 1902 1903 PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS); 1904 PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1); 1905 1906 PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF); 1907 PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR); 1908 1909 /* READ WRITE filter flag */ 1910 PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT); 1911 1912 /* VNODE filter flags */ 1913 PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE); 1914 PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE); 1915 PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND); 1916 PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB); 1917 PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK); 1918 PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME); 1919 PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE); 1920 1921 /* PROC filter flags */ 1922 PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT); 1923 PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK); 1924 PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC); 1925 PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK); 1926 PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK); 1927 1928 PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK); 1929 PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD); 1930 PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR); 1931 1932 /* NETDEV filter flags */ 1877 1933 #ifdef EVFILT_NETDEV 1878 1879 1880 1934 PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP); 1935 PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN); 1936 PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV); 1881 1937 #endif 1882 1938
Note:
See TracChangeset
for help on using the changeset viewer.