Index: /pjproject/trunk/pjsip/include/pjsip-simple/publish.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsip-simple/publish.h	(revision 2939)
+++ /pjproject/trunk/pjsip/include/pjsip-simple/publish.h	(revision 2940)
@@ -65,4 +65,23 @@
 typedef struct pjsip_publishc pjsip_publishc;
 
+
+/**
+ * Client publication options. Application should initialize this structure
+ * with its default values by calling #pjsip_publishc_opt_default()
+ */
+typedef struct pjsip_publishc_opt
+{
+    /**
+     * Specify whether the client publication session should queue the
+     * PUBLISH request should there be another PUBLISH transaction still
+     * pending. If this is set to false, the client will return error
+     * on the PUBLISH request if there is another PUBLISH transaction still
+     * in progress.
+     *
+     * Default: PJSIP_PUBLISHC_QUEUE_REQUEST
+     */
+    pj_bool_t	queue_request;
+
+} pjsip_publishc_opt;
 
 
@@ -90,4 +109,12 @@
 
 /**
+ * Initialize client publication session option with default values.
+ *
+ * @param opt	    The option.
+ */
+PJ_DECL(void) pjsip_publishc_opt_default(pjsip_publishc_opt *opt);
+
+
+/**
  * Initialize client publication module.
  *
@@ -99,10 +126,9 @@
 
 
-
 /**
  * Create client publication structure.
  *
  * @param endpt	    Endpoint, used to allocate pool from.
- * @param options   Option flags.
+ * @param opt	    Options, or NULL to specify default options.
  * @param token	    Opaque data to be associated with the client publication.
  * @param cb	    Pointer to callback function to receive publication status.
@@ -112,5 +138,5 @@
  */
 PJ_DECL(pj_status_t) pjsip_publishc_create( pjsip_endpoint *endpt, 
-					    unsigned options,
+					    const pjsip_publishc_opt *opt,
 					    void *token,
 				            pjsip_publishc_cb *cb, 
@@ -270,8 +296,21 @@
  * completes.
  *
+ * If the session has another PUBLISH request outstanding, the behavior
+ * depends on whether request queueing is enabled in the session (this was
+ * set by setting \a queue_request field of #pjsip_publishc_opt to true
+ * when calling #pjsip_publishc_create(). Default is true). If request
+ * queueing is enabled, the request will be queued and the function will 
+ * return PJ_EPENDING. One the outstanding request is complete, the queued
+ * request will be sent automatically. If request queueing is disabled, the
+ * function will reject the request and return PJ_EBUSY.
+ *
  * @param pubc	    The client publication structure.
  * @param tdata	    Transmit data.
  *
- * @return	    PJ_SUCCESS on success.
+ * @return	    - PJ_SUCCESS on success, or 
+ *		    - PJ_EPENDING if request is queued, or
+ *		    - PJ_EBUSY if request is rejected because another PUBLISH
+ *		      request is in progress, or
+ *		    - other status code to indicate the error.
  */
 PJ_DECL(pj_status_t) pjsip_publishc_send(pjsip_publishc *pubc, 
Index: /pjproject/trunk/pjsip/include/pjsip/sip_config.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsip/sip_config.h	(revision 2939)
+++ /pjproject/trunk/pjsip/include/pjsip/sip_config.h	(revision 2940)
@@ -897,4 +897,18 @@
 
 
+/**
+ * Specify whether the client publication session should queue the
+ * PUBLISH request should there be another PUBLISH transaction still
+ * pending. If this is set to false, the client will return error
+ * on the PUBLISH request if there is another PUBLISH transaction still
+ * in progress.
+ *
+ * Default: 1 (yes)
+ */
+#ifndef PJSIP_PUBLISHC_QUEUE_REQUEST
+#   define PJSIP_PUBLISHC_QUEUE_REQUEST		1
+#endif
+
+
 PJ_END_DECL
 
Index: /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 2939)
+++ /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 2940)
@@ -1798,4 +1798,9 @@
 
     /**
+     * Event publication options.
+     */
+    pjsip_publishc_opt	publish_opt;
+
+    /**
      * Authentication preference.
      */
Index: /pjproject/trunk/pjsip/src/pjsip-simple/publishc.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip-simple/publishc.c	(revision 2939)
+++ /pjproject/trunk/pjsip/src/pjsip-simple/publishc.c	(revision 2940)
@@ -58,4 +58,13 @@
 
 /**
+ * Pending request list.
+ */
+typedef struct pending_publish
+{
+    PJ_DECL_LIST_MEMBER(pjsip_tx_data);
+} pending_publish;
+
+
+/**
  * SIP client publication structure.
  */
@@ -66,5 +75,7 @@
     pj_bool_t			 _delete_flag;
     int				 pending_tsx;
-
+    pj_mutex_t			*mutex;
+
+    pjsip_publishc_opt		 opt;
     void			*token;
     pjsip_publishc_cb		*cb;
@@ -92,6 +103,15 @@
     pj_time_val			 next_refresh;
     pj_timer_entry		 timer;
+
+    /* Pending PUBLISH request */
+    pending_publish		 pending_reqs;
 };
 
+
+PJ_DEF(void) pjsip_publishc_opt_default(pjsip_publishc_opt *opt)
+{
+    pj_bzero(opt, sizeof(*opt));
+    opt->queue_request = PJSIP_PUBLISHC_QUEUE_REQUEST;
+}
 
 
@@ -128,5 +148,5 @@
 
 PJ_DEF(pj_status_t) pjsip_publishc_create( pjsip_endpoint *endpt, 
-					   unsigned options,
+					   const pjsip_publishc_opt *opt,
 					   void *token,
 					   pjsip_publishc_cb *cb,	
@@ -135,11 +155,9 @@
     pj_pool_t *pool;
     pjsip_publishc *pubc;
+    pjsip_publishc_opt default_opt;
     pj_status_t status;
 
     /* Verify arguments. */
     PJ_ASSERT_RETURN(endpt && cb && p_pubc, PJ_EINVAL);
-    PJ_ASSERT_RETURN(options == 0, PJ_EINVAL);
-
-    PJ_UNUSED_ARG(options);
 
     pool = pjsip_endpt_create_pool(endpt, "pubc%p", 1024, 1024);
@@ -154,7 +172,23 @@
     pubc->expires = PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED;
 
+    if (!opt) {
+	pjsip_publishc_opt_default(&default_opt);
+	opt = &default_opt;
+    }
+    pj_memcpy(&pubc->opt, opt, sizeof(*opt));
+    pj_list_init(&pubc->pending_reqs);
+
+    status = pj_mutex_create_recursive(pubc->pool, "pubc%p", &pubc->mutex);
+    if (status != PJ_SUCCESS) {
+	pj_pool_release(pool);
+	return status;
+    }
+
     status = pjsip_auth_clt_init(&pubc->auth_sess, endpt, pubc->pool, 0);
-    if (status != PJ_SUCCESS)
+    if (status != PJ_SUCCESS) {
+	pj_mutex_destroy(pubc->mutex);
+	pj_pool_release(pool);
 	return status;
+    }
 
     pj_list_init(&pubc->route_set);
@@ -181,4 +215,6 @@
 	}
 
+	if (pubc->mutex)
+	    pj_mutex_destroy(pubc->mutex);
 	pjsip_endpt_release_pool(pubc->endpt, pubc->pool);
     }
@@ -576,4 +612,10 @@
 	    if (pubc->auto_refresh && expiration!=0 && expiration!=0xFFFF) {
 		pj_time_val delay = { 0, 0};
+
+		/* Cancel existing timer, if any */
+		if (pubc->timer.id != 0) {
+		    pjsip_endpt_cancel_timer(pubc->endpt, &pubc->timer);
+		    pubc->timer.id = 0;
+		}
 
 		delay.sec = expiration - DELAY_BEFORE_REFRESH;
@@ -614,4 +656,20 @@
 
 	--pubc->pending_tsx;
+
+	/* If we have pending request(s), send them now */
+	pj_mutex_lock(pubc->mutex);
+	while (!pj_list_empty(&pubc->pending_reqs)) {
+	    pjsip_tx_data *tdata = pubc->pending_reqs.next;
+	    pj_list_erase(tdata);
+	    status = pjsip_publishc_send(pubc, tdata);
+	    if (status == PJ_EPENDING) {
+		pj_assert(!"Not expected");
+		pj_list_erase(tdata);
+		pjsip_tx_data_dec_ref(tdata);
+	    } else if (status == PJ_SUCCESS) {
+		break;
+	    }
+	}
+	pj_mutex_unlock(pubc->mutex);
     }
 
@@ -630,11 +688,24 @@
     pj_uint32_t cseq;
 
+    PJ_ASSERT_RETURN(pubc && tdata, PJ_EINVAL);
+
     /* Make sure we don't have pending transaction. */
+    pj_mutex_lock(pubc->mutex);
     if (pubc->pending_tsx) {
-	PJ_LOG(4,(THIS_FILE, "Unable to send request, pubc has another "
-			     "transaction pending"));
-	pjsip_tx_data_dec_ref( tdata );
-	return PJSIP_EBUSY;
-    }
+	if (pubc->opt.queue_request) {
+	    pj_list_push_back(&pubc->pending_reqs, tdata);
+	    pj_mutex_unlock(pubc->mutex);
+	    PJ_LOG(4,(THIS_FILE, "Request is queued, pubc has another "
+				 "transaction pending"));
+	    return PJ_EPENDING;
+	} else {
+	    pjsip_tx_data_dec_ref(tdata);
+	    pj_mutex_unlock(pubc->mutex);
+	    PJ_LOG(4,(THIS_FILE, "Unable to send request, pubc has another "
+				 "transaction pending"));
+	    return PJ_EBUSY;
+	}
+    }
+    pj_mutex_unlock(pubc->mutex);
 
     /* Invalidate message buffer. */
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 2939)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 2940)
@@ -162,4 +162,5 @@
 
     cfg->reg_timeout = PJSUA_REG_INTERVAL;
+    pjsip_publishc_opt_default(&cfg->publish_opt);
     cfg->transport_id = PJSUA_INVALID_ID;
     cfg->allow_contact_rewrite = PJ_TRUE;
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c	(revision 2939)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c	(revision 2940)
@@ -1074,5 +1074,8 @@
     /* Send the PUBLISH request */
     status = pjsip_publishc_send(acc->publish_sess, tdata);
-    if (status != PJ_SUCCESS) {
+    if (status == PJ_EPENDING) {
+	PJ_LOG(3,(THIS_FILE, "Previous request is in progress, "
+		  "PUBLISH request is queued"));
+    } else if (status != PJ_SUCCESS) {
 	pjsua_perror(THIS_FILE, "Error sending PUBLISH request", status);
 	goto on_error;
@@ -1103,5 +1106,6 @@
 
 	/* Create client publication */
-	status = pjsip_publishc_create(pjsua_var.endpt, 0, acc, &publish_cb,
+	status = pjsip_publishc_create(pjsua_var.endpt, &acc_cfg->publish_opt, 
+				       acc, &publish_cb,
 				       &acc->publish_sess);
 	if (status != PJ_SUCCESS) {
