Only works on UNIX; Windows has to wait for the GSocket port.
http://bugzilla.gnome.org/show_bug.cgi?id=578990
SoupConnectionState
soup_connection_get_state (SoupConnection *conn)
{
+ SoupConnectionPrivate *priv;
+
g_return_val_if_fail (SOUP_IS_CONNECTION (conn),
SOUP_CONNECTION_DISCONNECTED);
+ priv = SOUP_CONNECTION_GET_PRIVATE (conn);
+
+#ifdef G_OS_UNIX
+ if (priv->state == SOUP_CONNECTION_IDLE) {
+ GPollFD pfd;
+
+ pfd.fd = soup_socket_get_fd (priv->socket);
+ pfd.events = G_IO_IN;
+ pfd.revents = 0;
+ if (g_poll (&pfd, 1, 0) == 1)
+ priv->state = SOUP_CONNECTION_REMOTE_DISCONNECTED;
+ }
+#endif
- return SOUP_CONNECTION_GET_PRIVATE (conn)->state;
+ return priv->state;
}
void
SOUP_CONNECTION_CONNECTING,
SOUP_CONNECTION_IDLE,
SOUP_CONNECTION_IN_USE,
+ SOUP_CONNECTION_REMOTE_DISCONNECTED,
SOUP_CONNECTION_DISCONNECTED
} SoupConnectionState;
SoupConnection *conn;
gboolean try_pruning = TRUE, should_prune = FALSE;
+ soup_session_cleanup_connections (session, FALSE);
+
try_again:
for (item = soup_message_queue_first (queue);
item && !should_prune;
* could be sent if we pruned an idle connection from
* some other server.
*/
- if (soup_session_try_prune_connection (session)) {
+ if (soup_session_cleanup_connections (session, TRUE)) {
try_pruning = should_prune = FALSE;
goto try_again;
}
SoupConnection *soup_session_get_connection (SoupSession *session,
SoupMessageQueueItem *item,
gboolean *try_pruning);
-gboolean soup_session_try_prune_connection (SoupSession *session);
+gboolean soup_session_cleanup_connections (SoupSession *session,
+ gboolean prune_idle);
void soup_session_connection_failed (SoupSession *session,
SoupConnection *conn,
guint status);
g_mutex_lock (priv->lock);
+ soup_session_cleanup_connections (session, FALSE);
+
try_again:
conn = soup_session_get_connection (session, item, &try_pruning);
if (conn) {
return conn;
}
- if (try_pruning && soup_session_try_prune_connection (session))
- goto try_again;
+ if (try_pruning) {
+ try_pruning = FALSE;
+ if (soup_session_cleanup_connections (session, TRUE))
+ goto try_again;
+ }
/* Wait... */
g_cond_wait (priv->cond, priv->lock);
}
gboolean
-soup_session_try_prune_connection (SoupSession *session)
+soup_session_cleanup_connections (SoupSession *session,
+ gboolean prune_idle)
{
SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
- GPtrArray *conns;
+ GSList *conns = NULL, *c;
GHashTableIter iter;
gpointer conn, host;
- int i;
-
- conns = g_ptr_array_new ();
+ SoupConnectionState state;
g_mutex_lock (priv->host_lock);
g_hash_table_iter_init (&iter, priv->conns);
while (g_hash_table_iter_next (&iter, &conn, &host)) {
- /* Don't prune a connection that is currently in use,
- * or hasn't been used yet.
- */
- if (soup_connection_get_state (conn) == SOUP_CONNECTION_IDLE &&
- soup_connection_last_used (conn) > 0)
- g_ptr_array_add (conns, g_object_ref (conn));
+ state = soup_connection_get_state (conn);
+ if (state == SOUP_CONNECTION_REMOTE_DISCONNECTED ||
+ (prune_idle && state == SOUP_CONNECTION_IDLE &&
+ soup_connection_last_used (conn) > 0))
+ conns = g_slist_prepend (conns, g_object_ref (conn));
}
g_mutex_unlock (priv->host_lock);
- if (!conns->len) {
- g_ptr_array_free (conns, TRUE);
+ if (!conns)
return FALSE;
- }
- for (i = 0; i < conns->len; i++) {
- soup_connection_disconnect (conns->pdata[i]);
- g_object_unref (conns->pdata[i]);
+ for (c = conns; c; c = c->next) {
+ conn = c->data;
+ soup_connection_disconnect (conn);
+ g_object_unref (conn);
}
- g_ptr_array_free (conns, TRUE);
+ g_slist_free (conns);
return TRUE;
}
return status;
}
+int
+soup_socket_get_fd (SoupSocket *sock)
+{
+ g_return_val_if_fail (SOUP_IS_SOCKET (sock), -1);
+
+ return SOUP_SOCKET_GET_PRIVATE (sock)->sockfd;
+}
+
static gboolean
listen_watch (GIOChannel* iochannel, GIOCondition condition, gpointer data)
{
gpointer user_data);
guint soup_socket_connect_sync (SoupSocket *sock,
GCancellable *cancellable);
+int soup_socket_get_fd (SoupSocket *sock);
gboolean soup_socket_listen (SoupSocket *sock);