comparison src/scrobbler/plugin.c @ 353:1bd205b6e83d trunk

[svn] - replace g_usleep() with g_cond_timed_wait() - some bug fixes
author yaz
date Sat, 09 Dec 2006 08:32:41 -0800
parents b4f1ad07fcd9
children 958855dae693
comparison
equal deleted inserted replaced
352:7fc7b66c8a53 353:1bd205b6e83d
28 #include "config.h" 28 #include "config.h"
29 #include "fmt.h" 29 #include "fmt.h"
30 #include "configure.h" 30 #include "configure.h"
31 31
32 #define XS_CS xmms_scrobbler.xmms_session 32 #define XS_CS xmms_scrobbler.xmms_session
33 #define XS_SLEEP 1
34 #define HS_SLEEP 10
33 35
34 typedef struct submit_t 36 typedef struct submit_t
35 { 37 {
36 int dosubmit, pos_c, len; 38 int dosubmit, pos_c, len;
37 } submit_t; 39 } submit_t;
41 static void *xs_thread(void *); 43 static void *xs_thread(void *);
42 static void *hs_thread(void *); 44 static void *hs_thread(void *);
43 static int sc_going, ge_going, ha_going; 45 static int sc_going, ge_going, ha_going;
44 static GtkWidget *cfgdlg; 46 static GtkWidget *cfgdlg;
45 47
48 static GMutex *m_scrobbler;
46 static GThread *pt_scrobbler; 49 static GThread *pt_scrobbler;
47 static GMutex *m_scrobbler;
48 static GThread *pt_handshake; 50 static GThread *pt_handshake;
51
52 static GMutex *hs_mutex, *xs_mutex;
53 static GCond *hs_cond, *xs_cond;
49 54
50 static GeneralPlugin xmms_scrobbler = 55 static GeneralPlugin xmms_scrobbler =
51 { 56 {
52 NULL, 57 NULL,
53 NULL, 58 NULL,
65 char *ge_username = NULL, *ge_password = NULL; 70 char *ge_username = NULL, *ge_password = NULL;
66 char *ha_username = NULL, *ha_password = NULL; 71 char *ha_username = NULL, *ha_password = NULL;
67 ConfigDb *cfgfile; 72 ConfigDb *cfgfile;
68 sc_going = 1; 73 sc_going = 1;
69 ge_going = 1; 74 ge_going = 1;
75 ha_going = 1;
70 GError **moo = NULL; 76 GError **moo = NULL;
71 cfgdlg = create_cfgdlg(); 77 cfgdlg = create_cfgdlg();
72 78
73 prefswin_page_new(cfgdlg, "Scrobbler", DATA_DIR "/images/audioscrobbler.png"); 79 prefswin_page_new(cfgdlg, "Scrobbler", DATA_DIR "/images/audioscrobbler.png");
74 80
123 129
124 g_free(ha_username); 130 g_free(ha_username);
125 g_free(ha_password); 131 g_free(ha_password);
126 132
127 m_scrobbler = g_mutex_new(); 133 m_scrobbler = g_mutex_new();
128 if ((pt_scrobbler = g_thread_create(xs_thread, m_scrobbler, TRUE, moo)) == NULL) 134 hs_mutex = g_mutex_new();
135 xs_mutex = g_mutex_new();
136 hs_cond = g_cond_new();
137 xs_cond = g_cond_new();
138
139 if ((pt_scrobbler = g_thread_create(xs_thread, NULL, TRUE, moo)) == NULL)
129 { 140 {
130 pdebug(fmt_vastr("Error creating scrobbler thread: %s", moo), DEBUG); 141 pdebug(fmt_vastr("Error creating scrobbler thread: %s", moo), DEBUG);
131 sc_going = 0; 142 sc_going = 0;
132 ge_going = 0; 143 ge_going = 0;
133 ha_going = 0; 144 ha_going = 0;
134 return; 145 return;
135 } 146 }
136 147
137 if ((pt_handshake = g_thread_create(hs_thread, m_scrobbler, TRUE, NULL)) == NULL) 148 if ((pt_handshake = g_thread_create(hs_thread, NULL, TRUE, moo)) == NULL)
138 { 149 {
139 pdebug(fmt_vastr("Error creating handshake thread: %s", moo), DEBUG); 150 pdebug(fmt_vastr("Error creating handshake thread: %s", moo), DEBUG);
140 sc_going = 0; 151 sc_going = 0;
141 ge_going = 0; 152 ge_going = 0;
142 ha_going = 0; 153 ha_going = 0;
151 g_free (xmms_scrobbler.description); 162 g_free (xmms_scrobbler.description);
152 xmms_scrobbler.description = NULL; 163 xmms_scrobbler.description = NULL;
153 164
154 prefswin_page_destroy(cfgdlg); 165 prefswin_page_destroy(cfgdlg);
155 166
156 if (!sc_going && !ge_going) 167 if (!sc_going && !ge_going && ! ha_going)
157 return; 168 return;
158 pdebug("about to lock mutex", DEBUG); 169 pdebug("about to lock mutex", DEBUG);
159 g_mutex_lock(m_scrobbler); 170 g_mutex_lock(m_scrobbler);
160 pdebug("locked mutex", DEBUG); 171 pdebug("locked mutex", DEBUG);
161 sc_going = 0; 172 sc_going = 0;
162 ge_going = 0; 173 ge_going = 0;
174 ha_going = 0;
163 g_mutex_unlock(m_scrobbler); 175 g_mutex_unlock(m_scrobbler);
164 pdebug("joining threads", DEBUG); 176 pdebug("joining threads", DEBUG);
177
178 /* wake up waiting threads */
179 pdebug("send signal to xs and hs", DEBUG);
180 g_cond_signal(xs_cond);
181 g_cond_signal(hs_cond);
182
183 pdebug("wait xs", DEBUG);
165 g_thread_join(pt_scrobbler); 184 g_thread_join(pt_scrobbler);
166 185
186 pdebug("wait hs", DEBUG);
167 g_thread_join(pt_handshake); 187 g_thread_join(pt_handshake);
188
189 g_cond_free(hs_cond);
190 g_cond_free(xs_cond);
191 g_mutex_free(hs_mutex);
192 g_mutex_free(xs_mutex);
193 g_mutex_free(m_scrobbler);
168 194
169 sc_cleaner(); 195 sc_cleaner();
170 gerpok_sc_cleaner(); 196 gerpok_sc_cleaner();
171 hatena_sc_cleaner(); 197 hatena_sc_cleaner();
172 } 198 }
419 445
420 static void *xs_thread(void *data __attribute__((unused))) 446 static void *xs_thread(void *data __attribute__((unused)))
421 { 447 {
422 int run = 1; 448 int run = 1;
423 submit_t dosubmit; 449 submit_t dosubmit;
424 450 GTimeVal sleeptime;
451
425 while (run) { 452 while (run) {
426 /* Error catching */ 453 /* Error catching */
427 if(sc_catch_error()) 454 if(sc_catch_error())
428 { 455 {
429 errorbox_show(sc_fetch_error()); 456 errorbox_show(sc_fetch_error());
468 dosubmit.len/1000); 495 dosubmit.len/1000);
469 } 496 }
470 else 497 else
471 pdebug("tuple does not contain an artist or a title, not submitting.", DEBUG); 498 pdebug("tuple does not contain an artist or a title, not submitting.", DEBUG);
472 } 499 }
500 g_get_current_time(&sleeptime);
501 sleeptime.tv_sec += XS_SLEEP;
502
473 g_mutex_lock(m_scrobbler); 503 g_mutex_lock(m_scrobbler);
474 run = (sc_going != 0 || ge_going != 0 || ha_going != 0); 504 run = (sc_going != 0 || ge_going != 0 || ha_going != 0);
475 g_mutex_unlock(m_scrobbler); 505 g_mutex_unlock(m_scrobbler);
476 g_usleep(100000); 506
507 g_mutex_lock(xs_mutex);
508 g_cond_timed_wait(xs_cond, xs_mutex, &sleeptime);
509 g_mutex_unlock(xs_mutex);
477 } 510 }
478 pdebug("scrobbler thread: exiting", DEBUG); 511 pdebug("scrobbler thread: exiting", DEBUG);
479 g_thread_exit(NULL); 512 g_thread_exit(NULL);
480 513
481 return NULL; 514 return NULL;
482 } 515 }
483 516
484 static void *hs_thread(void *data __attribute__((unused))) 517 static void *hs_thread(void *data __attribute__((unused)))
485 { 518 {
486 int run = 1; 519 int run = 1;
487 520 GTimeVal sleeptime;
521
488 while(run) 522 while(run)
489 { 523 {
490 if(sc_idle(m_scrobbler)) 524 if(sc_idle(m_scrobbler))
491 { 525 {
492 pdebug("Giving up due to fatal error", DEBUG); 526 pdebug("Giving up due to fatal error", DEBUG);
493 g_mutex_lock(m_scrobbler); 527 g_mutex_lock(m_scrobbler);
494 sc_going = 0; 528 sc_going = 0;
495 g_mutex_lock(m_scrobbler); 529 g_mutex_unlock(m_scrobbler);
496 } 530 }
497 531
498 if(gerpok_sc_idle(m_scrobbler)) 532 if(gerpok_sc_idle(m_scrobbler))
499 { 533 {
500 pdebug("Giving up due to fatal error", DEBUG); 534 pdebug("Giving up due to fatal error", DEBUG);
501 g_mutex_lock(m_scrobbler); 535 g_mutex_lock(m_scrobbler);
502 ge_going = 0; 536 ge_going = 0;
503 g_mutex_lock(m_scrobbler); 537 g_mutex_unlock(m_scrobbler);
504 } 538 }
505 539
506 if(hatena_sc_idle(m_scrobbler)) 540 if(hatena_sc_idle(m_scrobbler))
507 { 541 {
508 pdebug("Giving up due to fatal error", DEBUG); 542 pdebug("Giving up due to fatal error", DEBUG);
509 g_mutex_lock(m_scrobbler); 543 g_mutex_lock(m_scrobbler);
510 ha_going = 0; 544 ha_going = 0;
511 g_mutex_lock(m_scrobbler); 545 g_mutex_unlock(m_scrobbler);
512 } 546 }
513 547
514 g_mutex_lock(m_scrobbler); 548 g_mutex_lock(m_scrobbler);
515 run = (sc_going != 0 || ge_going != 0 || ha_going != 0); 549 run = (sc_going != 0 || ge_going != 0 || ha_going != 0);
516 g_mutex_unlock(m_scrobbler); 550 g_mutex_unlock(m_scrobbler);
517 g_usleep(1000000); 551
552 if(run) {
553 g_get_current_time(&sleeptime);
554 sleeptime.tv_sec += HS_SLEEP;
555
556 g_mutex_lock(hs_mutex);
557 g_cond_timed_wait(hs_cond, hs_mutex, &sleeptime);
558 g_mutex_unlock(hs_mutex);
559 }
518 } 560 }
519 pdebug("handshake thread: exiting", DEBUG); 561 pdebug("handshake thread: exiting", DEBUG);
520 g_thread_exit(NULL); 562 g_thread_exit(NULL);
521 563
522 return NULL; 564 return NULL;