[statusbar] Implement multi-threading per statusbar

More more efficient than before.

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-05-27 11:17:51 +02:00
parent 7cdba19a56
commit a0b24c5505
5 changed files with 51 additions and 37 deletions

View File

@ -34,8 +34,6 @@
#include <fcntl.h> #include <fcntl.h>
#include <signal.h> #include <signal.h>
#include <pthread.h>
#include <glib.h> #include <glib.h>
#include <xcb/xcb.h> #include <xcb/xcb.h>
@ -49,7 +47,6 @@
#include "event.h" #include "event.h"
#include "layout.h" #include "layout.h"
#include "screen.h" #include "screen.h"
#include "statusbar.h"
#include "window.h" #include "window.h"
#include "client.h" #include "client.h"
#include "focus.h" #include "focus.h"
@ -65,12 +62,6 @@ bool running = true;
awesome_t globalconf; awesome_t globalconf;
#define a_thread_refresh(id, fct) \
do { \
if(pthread_create(id, NULL, fct, NULL)) \
perror("error creating thread\n"); \
} while(0)
typedef struct typedef struct
{ {
xcb_window_t id; xcb_window_t id;
@ -294,7 +285,6 @@ main(int argc, char **argv)
xcb_generic_event_t *ev; xcb_generic_event_t *ev;
struct sockaddr_un *addr; struct sockaddr_un *addr;
client_t *c; client_t *c;
pthread_t tid_statusbar;
static struct option long_options[] = static struct option long_options[] =
{ {
{"help", 0, NULL, 'h'}, {"help", 0, NULL, 'h'},
@ -341,6 +331,9 @@ main(int argc, char **argv)
/* Text won't be printed correctly otherwise */ /* Text won't be printed correctly otherwise */
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
/* initialize Glib for thread safeness */
g_thread_init(NULL);
/* X stuff */ /* X stuff */
globalconf.connection = xcb_connect(NULL, &globalconf.default_screen); globalconf.connection = xcb_connect(NULL, &globalconf.default_screen);
if(xcb_connection_has_error(globalconf.connection)) if(xcb_connection_has_error(globalconf.connection))
@ -483,12 +476,8 @@ main(int argc, char **argv)
signal(SIGHUP, &exit_on_signal); signal(SIGHUP, &exit_on_signal);
/* refresh everything before waiting events */ /* refresh everything before waiting events */
statusbar_refresh(NULL);
layout_refresh(); layout_refresh();
/* initialize Glib for thread safeness */
g_thread_init(NULL);
/* main event loop, also reads status text from socket */ /* main event loop, also reads status text from socket */
while(running) while(running)
{ {
@ -540,16 +529,12 @@ main(int argc, char **argv)
p_delete(&ev); p_delete(&ev);
} while((ev = xcb_poll_for_event(globalconf.connection))); } while((ev = xcb_poll_for_event(globalconf.connection)));
a_thread_refresh(&tid_statusbar, &statusbar_refresh);
layout_refresh(); layout_refresh();
pthread_join(tid_statusbar, NULL);
/* need to resync */ /* need to resync */
xcb_aux_sync(globalconf.connection); xcb_aux_sync(globalconf.connection);
} }
a_thread_refresh(&tid_statusbar, &statusbar_refresh);
layout_refresh(); layout_refresh();
pthread_join(tid_statusbar, NULL);
xcb_aux_sync(globalconf.connection); xcb_aux_sync(globalconf.connection);
} }

View File

@ -21,6 +21,9 @@
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
#include <pthread.h>
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <xcb/xcb_aux.h> #include <xcb/xcb_aux.h>
@ -31,6 +34,7 @@
#include "window.h" #include "window.h"
extern awesome_t globalconf; extern awesome_t globalconf;
extern bool running;
static void static void
statusbar_draw(statusbar_t *statusbar) statusbar_draw(statusbar_t *statusbar)
@ -39,7 +43,7 @@ statusbar_draw(statusbar_t *statusbar)
int left = 0, right = 0; int left = 0, right = 0;
area_t rectangle = { 0, 0, 0, 0, NULL, NULL }; area_t rectangle = { 0, 0, 0, 0, NULL, NULL };
statusbar->need_update = false; statusbar->need_update.value = false;
if(!statusbar->position) if(!statusbar->position)
return; return;
@ -81,6 +85,25 @@ statusbar_draw(statusbar_t *statusbar)
simplewindow_refresh_drawable(statusbar->sw); simplewindow_refresh_drawable(statusbar->sw);
} }
static void *
statusbar_refresh(void *p)
{
statusbar_t *statusbar = (statusbar_t *) p;
while(running)
{
pthread_mutex_lock(&statusbar->need_update.lock);
while(!statusbar->need_update.value)
pthread_cond_wait(&statusbar->need_update.cond, &statusbar->need_update.lock);
statusbar_draw(statusbar);
pthread_mutex_unlock(&statusbar->need_update.lock);
}
return NULL;
}
static void static void
statusbar_position_update(statusbar_t *statusbar, position_t position) statusbar_position_update(statusbar_t *statusbar, position_t position)
{ {
@ -276,19 +299,13 @@ statusbar_position_update(statusbar_t *statusbar, position_t position)
statusbar_draw(statusbar); statusbar_draw(statusbar);
} }
void * void
statusbar_refresh(void *p __attribute__ ((unused))) statusbar_needupdate(statusbar_t *statusbar)
{ {
int screen; pthread_mutex_lock(&statusbar->need_update.lock);
statusbar_t *statusbar; statusbar->need_update.value = true;
pthread_mutex_unlock(&statusbar->need_update.lock);
for(screen = 0; screen < globalconf.screens_info->nscreen; screen++) pthread_cond_broadcast(&statusbar->need_update.cond);
for(statusbar = globalconf.screens[screen].statusbar;
statusbar;
statusbar = statusbar->next)
if(statusbar->need_update)
statusbar_draw(statusbar);
return NULL;
} }
statusbar_t * statusbar_t *
@ -357,7 +374,7 @@ luaA_statusbar_widget_add(lua_State *L)
widget_t **widget = luaL_checkudata(L, 2, "widget"); widget_t **widget = luaL_checkudata(L, 2, "widget");
widget_node_t *w = p_new(widget_node_t, 1); widget_node_t *w = p_new(widget_node_t, 1);
(*sb)->need_update = true; statusbar_needupdate(*sb);
w->widget = *widget; w->widget = *widget;
widget_node_list_append(&(*sb)->widgets, w); widget_node_list_append(&(*sb)->widgets, w);
widget_ref(widget); widget_ref(widget);
@ -394,6 +411,12 @@ luaA_statusbar_add(lua_State *L)
(*sb)->screen = screen; (*sb)->screen = screen;
(*sb)->phys_screen = screen_virttophys(screen); (*sb)->phys_screen = screen_virttophys(screen);
/* Initialize thread stuffs and start it */
pthread_cond_init(&(*sb)->need_update.cond, NULL);
pthread_mutex_init(&(*sb)->need_update.lock, NULL);
if(pthread_create(&(*sb)->tid, NULL, statusbar_refresh, *sb))
perror("unable to create thread");
return 0; return 0;
} }

View File

@ -23,7 +23,6 @@
#define AWESOME_STATUSBAR_H #define AWESOME_STATUSBAR_H
#include "structs.h" #include "structs.h"
#include "widget.h"
#include "common/refcount.h" #include "common/refcount.h"
#include "common/swindow.h" #include "common/swindow.h"
@ -36,8 +35,8 @@ statusbar_delete(statusbar_t **statusbar)
p_delete(statusbar); p_delete(statusbar);
} }
void * statusbar_refresh(void *);
statusbar_t * statusbar_getbyname(int, const char *); statusbar_t * statusbar_getbyname(int, const char *);
void statusbar_needupdate(statusbar_t *);
DO_RCNT(statusbar_t, statusbar, statusbar_delete) DO_RCNT(statusbar_t, statusbar, statusbar_delete)
DO_SLIST(statusbar_t, statusbar, statusbar_delete) DO_SLIST(statusbar_t, statusbar, statusbar_delete)

View File

@ -211,7 +211,14 @@ struct statusbar_t
/** Draw context */ /** Draw context */
draw_context_t *ctx; draw_context_t *ctx;
/** Need update */ /** Need update */
bool need_update; struct
{
bool value;
pthread_mutex_t lock;
pthread_cond_t cond;
} need_update;
/** Thread id */
pthread_t tid;
/** Default colors */ /** Default colors */
struct struct
{ {

View File

@ -129,7 +129,7 @@ widget_invalidate_cache(int screen, int flags)
for(widget = statusbar->widgets; widget; widget = widget->next) for(widget = statusbar->widgets; widget; widget = widget->next)
if(widget->widget->cache_flags & flags) if(widget->widget->cache_flags & flags)
{ {
statusbar->need_update = true; statusbar_needupdate(statusbar);
break; break;
} }
} }
@ -148,7 +148,7 @@ widget_invalidate_statusbar_bywidget(widget_t *widget)
for(witer = statusbar->widgets; witer; witer = witer->next) for(witer = statusbar->widgets; witer; witer = witer->next)
if(witer->widget == widget) if(witer->widget == widget)
{ {
statusbar->need_update = true; statusbar_needupdate(statusbar);
break; break;
} }
} }