summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2011-03-31 05:54:16 +0000
committerBenny Prijono <bennylp@teluu.com>2011-03-31 05:54:16 +0000
commit791727f49f2a8abd1e4a042581ca03e137afe3a0 (patch)
tree1786a4575c02e7c6b8f97b0d6f7d2d521077c3d6
parent44601d3deeb255f498b9c2b58ea322871f1a91b9 (diff)
Fixed #1225: iPhone: UDP socket send error after waking up from background mode (thanks Joe Meade for the report)
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3491 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjlib/src/pj/ioqueue_common_abs.c48
-rw-r--r--pjlib/src/pj/ioqueue_select.c3
2 files changed, 46 insertions, 5 deletions
diff --git a/pjlib/src/pj/ioqueue_common_abs.c b/pjlib/src/pj/ioqueue_common_abs.c
index 07ed838c..bb368ace 100644
--- a/pjlib/src/pj/ioqueue_common_abs.c
+++ b/pjlib/src/pj/ioqueue_common_abs.c
@@ -312,11 +312,29 @@ void ioqueue_dispatch_write_event(pj_ioqueue_t *ioqueue, pj_ioqueue_key_t *h)
*/
//write_op->op = 0;
} else if (write_op->op == PJ_IOQUEUE_OP_SEND_TO) {
- send_rc = pj_sock_sendto(h->fd,
- write_op->buf+write_op->written,
- &sent, write_op->flags,
- &write_op->rmt_addr,
- write_op->rmt_addrlen);
+ int retry;
+ for (retry=0; retry<2; ++retry) {
+ send_rc = pj_sock_sendto(h->fd,
+ write_op->buf+write_op->written,
+ &sent, write_op->flags,
+ &write_op->rmt_addr,
+ write_op->rmt_addrlen);
+#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
+ PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
+ /* Special treatment for dead UDP sockets here, see ticket #1107 */
+ if (send_rc==PJ_STATUS_FROM_OS(EPIPE) && !IS_CLOSING(h) &&
+ h->fd_type==pj_SOCK_DGRAM())
+ {
+ PJ_PERROR(4,(THIS_FILE, send_rc,
+ "Send error for socket %d, retrying",
+ h->fd));
+ replace_udp_sock(h);
+ continue;
+ }
+#endif
+ break;
+ }
+
/* Can't do this. We only clear "op" after we're finished sending
* the whole buffer.
*/
@@ -917,12 +935,17 @@ PJ_DEF(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_key_t *key,
{
struct write_operation *write_op;
unsigned retry;
+#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
+ PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
+ pj_bool_t restart_retry = PJ_FALSE;
+#endif
pj_status_t status;
pj_ssize_t sent;
PJ_ASSERT_RETURN(key && op_key && data && length, PJ_EINVAL);
PJ_CHECK_STACK();
+retry_on_restart:
/* Check if key is closing. */
if (IS_CLOSING(key))
return PJ_ECANCELLED;
@@ -959,6 +982,21 @@ PJ_DEF(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_key_t *key,
* the error to caller.
*/
if (status != PJ_STATUS_FROM_OS(PJ_BLOCKING_ERROR_VAL)) {
+#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
+ PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
+ /* Special treatment for dead UDP sockets here, see ticket #1107 */
+ if (status==PJ_STATUS_FROM_OS(EPIPE) && !IS_CLOSING(key) &&
+ key->fd_type==pj_SOCK_DGRAM() && !restart_retry)
+ {
+ PJ_PERROR(4,(THIS_FILE, status,
+ "Send error for socket %d, retrying",
+ key->fd));
+ replace_udp_sock(key);
+ restart_retry = PJ_TRUE;
+ goto retry_on_restart;
+ }
+#endif
+
return status;
}
status = status;
diff --git a/pjlib/src/pj/ioqueue_select.c b/pjlib/src/pj/ioqueue_select.c
index 3125bae7..52b9ee78 100644
--- a/pjlib/src/pj/ioqueue_select.c
+++ b/pjlib/src/pj/ioqueue_select.c
@@ -125,7 +125,10 @@ struct pj_ioqueue_t
};
/* Proto */
+#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
+ PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
static pj_status_t replace_udp_sock(pj_ioqueue_key_t *h);
+#endif
/* Include implementation for common abstraction after we declare
* pj_ioqueue_key_t and pj_ioqueue_t.