110 #endif |
110 #endif |
111 #ifndef G_OS_WIN32 |
111 #ifndef G_OS_WIN32 |
112 /* the poll/select call is also performed on a control socket, that way |
112 /* the poll/select call is also performed on a control socket, that way |
113 * we can send special commands to control it |
113 * we can send special commands to control it |
114 */ |
114 */ |
115 #define SEND_COMMAND(set, command) \ |
115 /* FIXME: Shouldn't we check or return the return value |
|
116 * of write()? |
|
117 */ |
|
118 #define SEND_COMMAND(set, command, result) \ |
116 G_STMT_START { \ |
119 G_STMT_START { \ |
117 unsigned char c = command; \ |
120 unsigned char c = command; \ |
118 write (set->control_write_fd.fd, &c, 1); \ |
121 result = write (set->control_write_fd.fd, &c, 1); \ |
|
122 if (result > 0) \ |
|
123 set->control_pending++; \ |
119 } G_STMT_END |
124 } G_STMT_END |
120 |
125 |
121 #define READ_COMMAND(set, command, res) \ |
126 #define READ_COMMAND(set, command, res) \ |
122 G_STMT_START { \ |
127 G_STMT_START { \ |
123 res = read (set->control_read_fd.fd, &command, 1); \ |
128 if (set->control_pending > 0) { \ |
|
129 res = read (set->control_read_fd.fd, &command, 1); \ |
|
130 if (res == 1) \ |
|
131 set->control_pending--; \ |
|
132 } else \ |
|
133 res = 0; \ |
124 } G_STMT_END |
134 } G_STMT_END |
125 |
135 |
126 #define GST_POLL_CMD_WAKEUP 'W' /* restart the poll/select call */ |
136 #define GST_POLL_CMD_WAKEUP 'W' /* restart the poll/select call */ |
127 |
137 |
128 #else /* G_OS_WIN32 */ |
138 #else /* G_OS_WIN32 */ |
158 #ifndef G_OS_WIN32 |
168 #ifndef G_OS_WIN32 |
159 GstPollFD control_read_fd; |
169 GstPollFD control_read_fd; |
160 GstPollFD control_write_fd; |
170 GstPollFD control_write_fd; |
161 #else |
171 #else |
162 GArray *active_fds_ignored; |
172 GArray *active_fds_ignored; |
163 |
|
164 GArray *events; |
173 GArray *events; |
165 GArray *active_events; |
174 GArray *active_events; |
166 |
175 |
167 HANDLE wakeup_event; |
176 HANDLE wakeup_event; |
168 #endif |
177 #endif |
169 |
178 |
170 gboolean controllable; |
179 gboolean controllable; |
171 gboolean new_controllable; |
180 gboolean new_controllable; |
172 gboolean waiting; |
181 guint waiting; |
|
182 guint control_pending; |
173 gboolean flushing; |
183 gboolean flushing; |
|
184 gboolean timer; |
174 }; |
185 }; |
175 |
186 |
176 static gint |
187 static gint |
177 find_index (GArray * array, GstPollFD * fd) |
188 find_index (GArray * array, GstPollFD * fd) |
178 { |
189 { |
296 |
307 |
297 FD_ZERO (readfds); |
308 FD_ZERO (readfds); |
298 FD_ZERO (writefds); |
309 FD_ZERO (writefds); |
299 |
310 |
300 g_mutex_lock (set->lock); |
311 g_mutex_lock (set->lock); |
301 |
312 |
302 for (i = 0; i < set->active_fds->len; i++) { |
313 for (i = 0; i < set->active_fds->len; i++) { |
303 #ifndef __SYMBIAN32__ |
314 #ifndef __SYMBIAN32__ |
304 struct pollfd *pfd = &g_array_index (set->fds, struct pollfd, i); |
315 struct pollfd *pfd = &g_array_index (set->fds, struct pollfd, i); |
305 #else |
316 #else |
306 GPollFD *pfd = &g_array_index (set->fds, GPollFD, i); |
317 GPollFD *pfd = &g_array_index (set->fds, GPollFD, i); |
500 |
510 |
501 GstPoll *gst_poll_new (gboolean controllable) |
511 GstPoll *gst_poll_new (gboolean controllable) |
502 { |
512 { |
503 GstPoll *nset; |
513 GstPoll *nset; |
504 |
514 |
505 nset = g_new0 (GstPoll, 1); |
515 nset = g_slice_new0 (GstPoll); |
506 nset->lock = g_mutex_new (); |
516 nset->lock = g_mutex_new (); |
507 #ifndef G_OS_WIN32 |
517 #ifndef G_OS_WIN32 |
508 nset->mode = GST_POLL_MODE_AUTO; |
518 nset->mode = GST_POLL_MODE_AUTO; |
509 //rj nset->fds = g_array_new (FALSE, FALSE, sizeof (struct pollfd)); |
519 //rj nset->fds = g_array_new (FALSE, FALSE, sizeof (struct pollfd)); |
510 //rj nset->active_fds = g_array_new (FALSE, FALSE, sizeof (struct pollfd)); |
520 //rj nset->active_fds = g_array_new (FALSE, FALSE, sizeof (struct pollfd)); |
957 WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, idx); |
1006 WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, idx); |
958 |
1007 |
959 res = (wfd->events.iErrorCode[FD_CLOSE_BIT] != 0) || |
1008 res = (wfd->events.iErrorCode[FD_CLOSE_BIT] != 0) || |
960 (wfd->events.iErrorCode[FD_READ_BIT] != 0) || |
1009 (wfd->events.iErrorCode[FD_READ_BIT] != 0) || |
961 (wfd->events.iErrorCode[FD_WRITE_BIT] != 0) || |
1010 (wfd->events.iErrorCode[FD_WRITE_BIT] != 0) || |
962 (wfd->events.iErrorCode[FD_ACCEPT_BIT] != 0); |
1011 (wfd->events.iErrorCode[FD_ACCEPT_BIT] != 0) || |
|
1012 (wfd->events.iErrorCode[FD_CONNECT_BIT] != 0); |
963 #endif |
1013 #endif |
964 } |
1014 } |
965 |
1015 |
966 g_mutex_unlock (set->lock); |
1016 g_mutex_unlock (set->lock); |
967 |
1017 |
1111 * @timeout: a timeout in nanoseconds. |
1163 * @timeout: a timeout in nanoseconds. |
1112 * |
1164 * |
1113 * Wait for activity on the file descriptors in @set. This function waits up to |
1165 * Wait for activity on the file descriptors in @set. This function waits up to |
1114 * the specified @timeout. A timeout of #GST_CLOCK_TIME_NONE waits forever. |
1166 * the specified @timeout. A timeout of #GST_CLOCK_TIME_NONE waits forever. |
1115 * |
1167 * |
1116 * When this function is called from multiple threads, -1 will be returned with |
1168 * For #GstPoll objects created with gst_poll_new(), this function can only be |
1117 * errno set to EPERM. |
1169 * called from a single thread at a time. If called from multiple threads, |
|
1170 * -1 will be returned with errno set to EPERM. |
|
1171 * |
|
1172 * This is not true for timer #GstPoll objects created with |
|
1173 * gst_poll_new_timer(), where it is allowed to have multiple threads waiting |
|
1174 * simultaneously. |
1118 * |
1175 * |
1119 * Returns: The number of #GstPollFD in @set that have activity or 0 when no |
1176 * Returns: The number of #GstPollFD in @set that have activity or 0 when no |
1120 * activity was detected after @timeout. If an error occurs, -1 is returned |
1177 * activity was detected after @timeout. If an error occurs, -1 is returned |
1121 * and errno is set. |
1178 * and errno is set. |
1122 * |
1179 * |
1124 */ |
1181 */ |
1125 #ifdef __SYMBIAN32__ |
1182 #ifdef __SYMBIAN32__ |
1126 EXPORT_C |
1183 EXPORT_C |
1127 #endif |
1184 #endif |
1128 |
1185 |
1129 gint gst_poll_wait (GstPoll * set, GstClockTime timeout) |
1186 gint |
|
1187 gst_poll_wait (GstPoll * set, GstClockTime timeout) |
1130 { |
1188 { |
1131 gboolean restarting; |
1189 gboolean restarting; |
1132 int res = -1; |
1190 int res; |
1133 |
1191 |
1134 g_return_val_if_fail (set != NULL, -1); |
1192 g_return_val_if_fail (set != NULL, -1); |
1135 |
1193 |
1136 g_mutex_lock (set->lock); |
1194 g_mutex_lock (set->lock); |
1137 |
1195 |
1138 /* we cannot wait from multiple threads */ |
1196 /* we cannot wait from multiple threads unless we are a timer */ |
1139 if (set->waiting) |
1197 if (G_UNLIKELY (set->waiting > 0 && !set->timer)) |
1140 goto already_waiting; |
1198 goto already_waiting; |
1141 |
1199 |
1142 /* flushing, exit immediatly */ |
1200 /* flushing, exit immediatly */ |
1143 if (set->flushing) |
1201 if (G_UNLIKELY (set->flushing)) |
1144 goto flushing; |
1202 goto flushing; |
1145 |
1203 |
1146 set->waiting = TRUE; |
1204 /* add one more waiter */ |
|
1205 set->waiting++; |
1147 |
1206 |
1148 do { |
1207 do { |
1149 GstPollMode mode; |
1208 GstPollMode mode; |
1150 |
1209 |
1151 res = -1; |
1210 res = -1; |
1330 } |
1389 } |
1331 } |
1390 } |
1332 |
1391 |
1333 g_mutex_lock (set->lock); |
1392 g_mutex_lock (set->lock); |
1334 |
1393 |
1335 gst_poll_check_ctrl_commands (set, res, &restarting); |
1394 if (!set->timer) |
|
1395 gst_poll_check_ctrl_commands (set, res, &restarting); |
1336 |
1396 |
1337 /* update the controllable state if needed */ |
1397 /* update the controllable state if needed */ |
1338 set->controllable = set->new_controllable; |
1398 set->controllable = set->new_controllable; |
1339 |
1399 |
1340 if (set->flushing) { |
1400 if (G_UNLIKELY (set->flushing)) { |
1341 /* we got woken up and we are flushing, we need to stop */ |
1401 /* we got woken up and we are flushing, we need to stop */ |
1342 errno = EBUSY; |
1402 errno = EBUSY; |
1343 res = -1; |
1403 res = -1; |
1344 break; |
1404 break; |
1345 } |
1405 } |
1346 } while (restarting); |
1406 } while (G_UNLIKELY (restarting)); |
1347 |
1407 |
1348 set->waiting = FALSE; |
1408 set->waiting--; |
1349 |
1409 |
1350 g_mutex_unlock (set->lock); |
1410 g_mutex_unlock (set->lock); |
1351 |
1411 |
1352 return res; |
1412 return res; |
1353 |
1413 |
1401 gint control_sock[2]; |
1463 gint control_sock[2]; |
1402 /* rj |
1464 /* rj |
1403 if (socketpair (PF_UNIX, SOCK_STREAM, 0, control_sock) < 0) |
1465 if (socketpair (PF_UNIX, SOCK_STREAM, 0, control_sock) < 0) |
1404 goto no_socket_pair; |
1466 goto no_socket_pair; |
1405 */ |
1467 */ |
|
1468 pipe(control_sock); |
1406 fcntl (control_sock[0], F_SETFL, O_NONBLOCK); |
1469 fcntl (control_sock[0], F_SETFL, O_NONBLOCK); |
1407 fcntl (control_sock[1], F_SETFL, O_NONBLOCK); |
1470 fcntl (control_sock[1], F_SETFL, O_NONBLOCK); |
1408 |
1471 |
1409 set->control_read_fd.fd = control_sock[0]; |
1472 set->control_read_fd.fd = control_sock[0]; |
1410 set->control_write_fd.fd = control_sock[1]; |
1473 set->control_write_fd.fd = control_sock[1]; |
1448 */ |
1511 */ |
1449 #ifdef __SYMBIAN32__ |
1512 #ifdef __SYMBIAN32__ |
1450 EXPORT_C |
1513 EXPORT_C |
1451 #endif |
1514 #endif |
1452 |
1515 |
1453 void gst_poll_restart (GstPoll * set) |
1516 void |
|
1517 gst_poll_restart (GstPoll * set) |
1454 { |
1518 { |
1455 g_return_if_fail (set != NULL); |
1519 g_return_if_fail (set != NULL); |
1456 |
1520 |
1457 g_mutex_lock (set->lock); |
1521 g_mutex_lock (set->lock); |
1458 |
1522 |
1459 if (set->controllable && set->waiting) { |
1523 if (set->controllable && set->waiting > 0) { |
1460 #ifndef G_OS_WIN32 |
1524 #ifndef G_OS_WIN32 |
|
1525 gint result; |
|
1526 |
1461 /* if we are waiting, we can send the command, else we do not have to |
1527 /* if we are waiting, we can send the command, else we do not have to |
1462 * bother, future calls will automatically pick up the new fdset */ |
1528 * bother, future calls will automatically pick up the new fdset */ |
1463 SEND_COMMAND (set, GST_POLL_CMD_WAKEUP); |
1529 SEND_COMMAND (set, GST_POLL_CMD_WAKEUP, result); |
1464 #else |
1530 #else |
1465 SetEvent (set->wakeup_event); |
1531 SetEvent (set->wakeup_event); |
1466 #endif |
1532 #endif |
1467 } |
1533 } |
1468 |
1534 |
1483 */ |
1549 */ |
1484 #ifdef __SYMBIAN32__ |
1550 #ifdef __SYMBIAN32__ |
1485 EXPORT_C |
1551 EXPORT_C |
1486 #endif |
1552 #endif |
1487 |
1553 |
1488 void gst_poll_set_flushing (GstPoll * set, gboolean flushing) |
1554 void |
|
1555 gst_poll_set_flushing (GstPoll * set, gboolean flushing) |
1489 { |
1556 { |
1490 g_return_if_fail (set != NULL); |
1557 g_return_if_fail (set != NULL); |
1491 |
1558 |
1492 g_mutex_lock (set->lock); |
1559 g_mutex_lock (set->lock); |
1493 |
1560 |
1494 /* update the new state first */ |
1561 /* update the new state first */ |
1495 set->flushing = flushing; |
1562 set->flushing = flushing; |
1496 |
1563 |
1497 if (flushing && set->controllable && set->waiting) { |
1564 if (flushing && set->controllable && set->waiting > 0) { |
1498 /* we are flushing, controllable and waiting, wake up the waiter. When we |
1565 /* we are flushing, controllable and waiting, wake up the waiter. When we |
1499 * stop the flushing operation we don't clear the wakeup fd here, this will |
1566 * stop the flushing operation we don't clear the wakeup fd here, this will |
1500 * happen in the _wait() thread. */ |
1567 * happen in the _wait() thread. */ |
1501 #ifndef G_OS_WIN32 |
1568 #ifndef G_OS_WIN32 |
1502 SEND_COMMAND (set, GST_POLL_CMD_WAKEUP); |
1569 gint result; |
|
1570 |
|
1571 SEND_COMMAND (set, GST_POLL_CMD_WAKEUP, result); |
1503 #else |
1572 #else |
1504 SetEvent (set->wakeup_event); |
1573 SetEvent (set->wakeup_event); |
1505 #endif |
1574 #endif |
1506 } |
1575 } |
1507 |
1576 |
1508 g_mutex_unlock (set->lock); |
1577 g_mutex_unlock (set->lock); |
1509 } |
1578 } |
|
1579 |
|
1580 /** |
|
1581 * gst_poll_write_control: |
|
1582 * @set: a #GstPoll. |
|
1583 * |
|
1584 * Write a byte to the control socket of the controllable @set. |
|
1585 * This function is mostly useful for timer #GstPoll objects created with |
|
1586 * gst_poll_new_timer(). |
|
1587 * |
|
1588 * It will make any current and future gst_poll_wait() function return with |
|
1589 * 1, meaning the control socket is set. After an equal amount of calls to |
|
1590 * gst_poll_read_control() have been performed, calls to gst_poll_wait() will |
|
1591 * block again until their timeout expired. |
|
1592 * |
|
1593 * Returns: %TRUE on success. %FALSE when @set is not controllable or when the |
|
1594 * byte could not be written. |
|
1595 * |
|
1596 * Since: 0.10.23 |
|
1597 */ |
|
1598 #ifdef __SYMBIAN32__ |
|
1599 EXPORT_C |
|
1600 #endif |
|
1601 |
|
1602 gboolean |
|
1603 gst_poll_write_control (GstPoll * set) |
|
1604 { |
|
1605 gboolean res = FALSE; |
|
1606 |
|
1607 g_return_val_if_fail (set != NULL, FALSE); |
|
1608 |
|
1609 g_mutex_lock (set->lock); |
|
1610 if (set->controllable) { |
|
1611 #ifndef G_OS_WIN32 |
|
1612 gint result; |
|
1613 |
|
1614 SEND_COMMAND (set, GST_POLL_CMD_WAKEUP, result); |
|
1615 res = (result > 0); |
|
1616 #else |
|
1617 res = SetEvent (set->wakeup_event); |
|
1618 #endif |
|
1619 } |
|
1620 g_mutex_unlock (set->lock); |
|
1621 |
|
1622 return res; |
|
1623 } |
|
1624 |
|
1625 /** |
|
1626 * gst_poll_read_control: |
|
1627 * @set: a #GstPoll. |
|
1628 * |
|
1629 * Read a byte from the control socket of the controllable @set. |
|
1630 * This function is mostly useful for timer #GstPoll objects created with |
|
1631 * gst_poll_new_timer(). |
|
1632 * |
|
1633 * Returns: %TRUE on success. %FALSE when @set is not controllable or when there |
|
1634 * was no byte to read. |
|
1635 * |
|
1636 * Since: 0.10.23 |
|
1637 */ |
|
1638 #ifdef __SYMBIAN32__ |
|
1639 EXPORT_C |
|
1640 #endif |
|
1641 |
|
1642 gboolean |
|
1643 gst_poll_read_control (GstPoll * set) |
|
1644 { |
|
1645 gboolean res = FALSE; |
|
1646 |
|
1647 g_return_val_if_fail (set != NULL, FALSE); |
|
1648 |
|
1649 g_mutex_lock (set->lock); |
|
1650 if (set->controllable) { |
|
1651 #ifndef G_OS_WIN32 |
|
1652 guchar cmd; |
|
1653 gint result; |
|
1654 READ_COMMAND (set, cmd, result); |
|
1655 res = (result > 0); |
|
1656 #else |
|
1657 res = ResetEvent (set->wakeup_event); |
|
1658 #endif |
|
1659 } |
|
1660 g_mutex_unlock (set->lock); |
|
1661 |
|
1662 return res; |
|
1663 } |