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;
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