GlusterFS context(glusterfs_ctx) has a timer data structure(gf_timer_registert_t).
gf_timer_registert_t {
pthread_t th,
char fin, // finish
_gf_timer stale, // stale event list
_gf_timer active, // active event list
pthread_mutex_t lock
}
There are - pthread
- active list
- stale list
- pthread lok
_gf_timer {
_gf_timer *next, *prev, // pointer to next and previous
timespec at, // time to execute the event
gf_timer_cbk_t callbk, // execute funcation
void data, // event data for callbk
xlator_t *xl // event translator
}
glusterfs_ctx timer
glusterfs_ctx will create a pthread, and pthread will execute gf_timer_proc() function.The thread will get the timer event from active list and check the timestamp of event. if timestamp > current time, it will move the timer event from active list to stale list, and execute the callback function of timer event.
gf_timer_proc code:
gf_timer_proc (void *ctx)
{
reg = gf_timer_registry_init (ctx);
while (!reg->fin) {
timespec_now (&now_ts);
/*get current time*/
now = TS (now_ts);
while (1) {
char need_cbk = 0;
pthread_mutex_lock (®->lock);
{
event = reg->active.next;
/*get event*/
at = TS (event->at);
/*get the event execute timing*/
if (event != ®->active && now >= at) {
/*if event is reg->active mean no event
now >= at mean it is the timing to execute the event*/
need_cbk = 1;
gf_timer_call_stale (reg, event);
/*move event from req->active to req->stale list*/
}
}
pthread_mutex_unlock (®->lock);
if (event->xl)
THIS = event->xl;
if (need_cbk)
event->callbk (event->data);
/*execute the event funcation*/
else
break;
}
nanosleep (&sleepts, NULL);
}
/* deconstruc the gf_timer data...*/
return NULL;
gf_timer_call_after() and glusterfs context timer
gf_timer_call_after() will create a new timer event and put it to active list of ctx->timergf_timer_call_after(glusterfs_ctx_t *ctx, struct timespec delta, gf_timer_cbk_t callbk, void *data))

.png)
沒有留言:
張貼留言