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