Somebody claiming to be Max Kellermann wrote:
> On 2009/04/07 19:01, Stephen Paul Weber <singpol...@singpolyma.net> wrote:
> > Attached please find 5 patch files, each the output of a git show
> > for 5 commits that progressively implement this feature :)
> 
> Found a major problem: conn.c does not deal with more than one
> connection at a time.  There's the global variable "g", which needs to
> be converted to a parameter, so we have a per-server "conn" object.
> 
> Result:
> 
>  mpdscribble: src/conn.c:89: conn_initiate: Assertion `!g.pending' failed.

Attached is a patch to deal with that :)

-- 
Stephen Paul Weber, @singpolyma
Please see <http://singpolyma.net> for how I prefer to be contacted.
nerve perfume pogo.
commit 7c960b224524ee6471faf8f146fbf1dec3dae352
Author: Stephen Paul Weber <singpol...@singpolyma.net>
Date:   Wed Apr 8 17:15:28 2009 -0400

    Get rid of globals for conn.c

diff --git a/src/as.c b/src/as.c
index 629d351..d87bae0 100644
--- a/src/as.c
+++ b/src/as.c
@@ -413,7 +413,7 @@ static void as_handshake(struct config_as_host *as_host)
 
 	//  notice ("handshake url:\n%s", url);
 
-	if (!conn_initiate(url->str, &as_handshake_callback, NULL, as_host)) {
+	if (!conn_initiate(url->str, &as_handshake_callback, NULL, as_host, as_host->conn)) {
 		g_warning("something went wrong when trying to connect, "
 			  "probably a bug\n");
 
@@ -472,7 +472,7 @@ as_send_now_playing(const char *artist, const char *track,
 	g_message("sending 'now playing' notification to '%s'\n", as_host->url);
 
 	if (!conn_initiate(as_host->g_nowplay_url, as_submit_callback,
-			   post_data->str, as_host)) {
+			   post_data->str, as_host, as_host->conn)) {
 		g_warning("failed to POST to %s\n", as_host->g_nowplay_url);
 
 		as_host->g_state = AS_READY;
@@ -559,7 +559,7 @@ static void as_submit(struct config_as_host *as_host)
 
 	g_submit_pending = count;
 	if (!conn_initiate(as_host->g_submit_url, &as_submit_callback,
-			   post_data->str, as_host)) {
+			   post_data->str, as_host, as_host->conn)) {
 		g_warning("something went wrong when trying to connect,"
 			  " probably a bug\n");
 
@@ -635,9 +635,8 @@ void as_init(void)
 	g_message("loaded %i song%s from cache\n",
 		  queue_length, queue_length == 1 ? "" : "s");
 
-	conn_setup();
-
 	do {
+		current_host->conn = conn_setup();
 		current_host->g_session = NULL;
 		current_host->g_nowplay_url = NULL;
 		current_host->g_submit_url = NULL;
@@ -695,6 +694,4 @@ void as_cleanup(void)
 
 	g_queue_foreach(queue, free_queue_song, NULL);
 	g_queue_free(queue);
-
-	conn_cleanup();
 }
diff --git a/src/conn.c b/src/conn.c
index 6214d82..56cbff4 100644
--- a/src/conn.c
+++ b/src/conn.c
@@ -21,29 +21,13 @@
 #include "conn.h"
 #include "file.h"
 #include "as.h"
-#include "config.h"
-
-#include <libsoup/soup-uri.h>
-#include <libsoup/soup-session-async.h>
 
 #include <assert.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 
-struct global {
-	SoupSession *session;
-	char *base;
-	bool pending;
-	callback_t *callback;
-#ifdef HAVE_SOUP_24
-	SoupURI *proxy;
-#else
-	SoupUri *proxy;
-#endif
-};
-
-static struct global g;
+int g_thread_done = 0;
 
 static void
 #ifdef HAVE_SOUP_24
@@ -53,51 +37,62 @@ conn_callback(G_GNUC_UNUSED SoupSession * session,
 conn_callback(SoupMessage * msg, gpointer data)
 #endif
 {
-	assert(g.pending);
+	struct global *g = data;
+	assert(g->pending);
 
-	g.pending = false;
+	g->pending = false;
 
 	/* NOTE: does not support redirects */
 	if (SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) {
 #ifdef HAVE_SOUP_24
-		g.callback(msg->response_body->length,
-			   msg->response_body->data, data);
+		g->callback(msg->response_body->length,
+			   msg->response_body->data, g->data);
 #else
-		g.callback(msg->response.length, msg->response.body, data);
+		g->callback(msg->response.length, msg->response.body, g->data);
 #endif
 	} else
-		g.callback(0, NULL, data);
+		g->callback(0, NULL, g->data);
 }
 
-void conn_setup(void)
+struct global *conn_setup(void)
 {
-	g_type_init();
-	g_thread_init(NULL);
 
-	g.pending = false;
+	if(!g_thread_done) {
+		g_type_init();
+		g_thread_init(NULL);
+		g_thread_done = 1;
+	}
+
+	struct global *g = malloc(sizeof *g);
+
+	g->pending = false;
 	if (file_config.proxy != NULL)
-		g.proxy = soup_uri_new(file_config.proxy);
+		g->proxy = soup_uri_new(file_config.proxy);
 	else
-		g.proxy = NULL;
+		g->proxy = NULL;
+
+	return g;
 }
 
 int
-conn_initiate(char *url, callback_t * callback, char *post_data, void *data)
+conn_initiate(char *url, callback_t * callback, char *post_data, void *data, struct global *g)
 {
 	SoupMessage *msg;
 
-	assert(!g.pending);
+	assert(!g->pending);
+
+	g->data = data;
 
-	g.callback = callback;
+	g->callback = callback;
 
-	g.base = url;
+	g->base = url;
 
-	g.session =
-	    soup_session_async_new_with_options(SOUP_SESSION_PROXY_URI, g.proxy,
+	g->session =
+	    soup_session_async_new_with_options(SOUP_SESSION_PROXY_URI, g->proxy,
 						NULL);
 
 	if (post_data) {
-		msg = soup_message_new(SOUP_METHOD_POST, g.base);
+		msg = soup_message_new(SOUP_METHOD_POST, g->base);
 #ifdef HAVE_SOUP_24
 		soup_message_set_request
 		    (msg, "application/x-www-form-urlencoded",
@@ -120,22 +115,23 @@ conn_initiate(char *url, callback_t * callback, char *post_data, void *data)
 		soup_message_add_header(msg->request_headers, "Accept", "*/*");
 #endif
 	} else {
-		msg = soup_message_new(SOUP_METHOD_GET, g.base);
+		msg = soup_message_new(SOUP_METHOD_GET, g->base);
 	}
 
 	soup_message_set_flags(msg, SOUP_MESSAGE_NO_REDIRECT);
 
-	g.pending = true;
-	soup_session_queue_message(g.session, msg, conn_callback, data);
+	g->pending = true;
+	soup_session_queue_message(g->session, msg, conn_callback, g);
 
 	return CONN_OK;
 }
 
-bool conn_pending(void)
+bool conn_pending(struct global *g)
 {
-	return g.pending;
+	return g->pending;
 }
 
-void conn_cleanup(void)
+void conn_cleanup(struct global *g)
 {
+	free(g);
 }
diff --git a/src/conn.h b/src/conn.h
index 918e925..3542acf 100644
--- a/src/conn.h
+++ b/src/conn.h
@@ -24,18 +24,36 @@
 #include <stdbool.h>
 #include <stddef.h>
 
+#include <libsoup/soup-uri.h>
+#include <libsoup/soup-session-async.h>
+
+#include "config.h"
+
 typedef void callback_t(size_t, const char *, void *);
 
+struct global {
+	SoupSession *session;
+	char *base;
+	void *data;
+	bool pending;
+	callback_t *callback;
+#ifdef HAVE_SOUP_24
+	SoupURI *proxy;
+#else
+	SoupUri *proxy;
+#endif
+};
+
 #define CONN_FAIL 0
 #define CONN_OK 1
 
 #define conn_escape(X) curl_escape(X, 0)
 #define conn_free curl_free
 
-void conn_setup(void);
-void conn_cleanup(void);
+struct global *conn_setup(void);
+void conn_cleanup(struct global *g);
 
-int conn_initiate(char *url, callback_t * callback, char *post_data, void *data);
-bool conn_pending(void);
+int conn_initiate(char *url, callback_t * callback, char *post_data, void *data, struct global *g);
+bool conn_pending(struct global *g);
 
 #endif /* CONN_H */
diff --git a/src/file.c b/src/file.c
index ac4fae5..2e3c8a6 100644
--- a/src/file.c
+++ b/src/file.c
@@ -330,6 +330,8 @@ int file_read_config(int argc, char **argv)
 
 void free_as_host(struct config_as_host *current_host)
 {
+	if(current_host->conn)
+		conn_cleanup(current_host->conn);
 	if(current_host->url)
 		free(current_host->url);
 	if(current_host->username)
diff --git a/src/file.h b/src/file.h
index c0a54e5..00afaea 100644
--- a/src/file.h
+++ b/src/file.h
@@ -21,6 +21,7 @@
 #define FILE_H
 
 #include <glib.h>
+#include "conn.h"
 
 enum file_location { file_etc, file_home, file_unknown, };
 
@@ -38,6 +39,7 @@ struct config_as_host {
 	char *password;
 	struct config_as_host *next; /* Linked list if more than one */
 	/* state stuff to get passed along in as.c */
+	struct global *conn;
 	guint as_handshake_id;
 	guint as_submit_id;
 	char *g_session;

Attachment: signature.asc
Description: Digital signature

------------------------------------------------------------------------------
This SF.net email is sponsored by:
High Quality Requirements in a Collaborative Environment.
Download a free trial of Rational Requirements Composer Now!
http://p.sf.net/sfu/www-ibm-com
_______________________________________________
Musicpd-dev-team mailing list
Musicpd-dev-team@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/musicpd-dev-team

Reply via email to