source: trunk/libtransmission/timer.c @ 2843

Last change on this file since 2843 was 2843, checked in by charles, 15 years ago

update version.sh to exclude third-party. add $Id:$ to the new files s.t. version.sh will find them.

File size: 2.5 KB
Line 
1/*
2 * This file Copyright (C) 2007 Charles Kerr <charles@rebelbase.com>
3 *
4 * This file is licensed by the GPL version 2.  Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id:
11 */
12
13#include <assert.h>
14
15#include <sys/types.h> /* u_char for event.h */
16#include <event.h>
17
18#include "transmission.h"
19#include "trevent.h"
20#include "timer.h"
21#include "utils.h"
22
23typedef int tr_timer_func ( void * user_data );
24typedef void tr_data_free_func( void * user_data );
25
26/***
27****
28***/
29
30struct timer_node
31{
32    tr_handle_t * handle;
33    struct event * event;
34    tr_timer_func * func;
35    void * user_data;
36    tr_data_free_func * free_func;
37    struct timeval tv;
38    int refcount;
39};
40
41static void
42unref( struct timer_node * node, int count )
43{
44    assert( node != NULL );
45    assert( node->refcount > 0 );
46
47    node->refcount -= count;
48    if( node->refcount > 0 )
49        return;
50
51    if( node->free_func != NULL )
52        (node->free_func)( node->user_data );
53    tr_event_del( node->handle, node->event );
54    tr_free( node );
55}
56
57void
58tr_timerFree( struct timer_node ** node )
59{
60    assert( node != NULL );
61
62    if( *node )
63    {
64        unref( *node, 1 );
65        *node = NULL;
66    }
67}
68
69static void
70timerCB( int fd UNUSED, short event UNUSED, void * arg )
71{
72    struct timer_node * node = (struct timer_node *) arg;
73    int val;
74
75    ++node->refcount;
76    val = (node->func)(node->user_data);
77    if( !val )
78        unref( node, 2 );
79    else {
80        timeout_add( node->event, &node->tv );
81        unref( node, 1 );
82    }
83}
84
85
86tr_timer_tag
87tr_timerNew( tr_handle_t        * handle,
88             tr_timer_func        func,
89             void               * user_data,
90             tr_data_free_func    free_func,
91             int                  timeout_milliseconds )
92{
93    struct timer_node * node;
94    const unsigned long microseconds = timeout_milliseconds * 1000;
95
96    assert( func != NULL );
97    assert( timeout_milliseconds >= 0 );
98
99    node = tr_new( struct timer_node, 1 );
100    node->handle = handle;
101    node->event = tr_new0( struct event, 1 );
102    node->func = func;
103    node->user_data = user_data;
104    node->free_func = free_func;
105    node->refcount = 1;
106    node->tv.tv_sec  = microseconds / 1000000;
107    node->tv.tv_usec = microseconds % 1000000;
108    timeout_set( node->event, timerCB, node );
109    tr_event_add( handle, node->event, &node->tv );
110    return node;
111}
Note: See TracBrowser for help on using the repository browser.