00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef lint
00021 static const char rcsid[] = "$Id: socktimer.c,v 1.1 2008-11-02 17:46:13 sven Exp $";
00022 #endif
00023
00024 #include <eggdrop/eggdrop.h>
00025 #include <unistd.h>
00026
00027 #define SOCKTIMER_LEVEL SOCKBUF_LEVEL_INTERNAL + 2
00028
00029 typedef struct {
00030 int idx;
00031 int timerid;
00032 int timerflags;
00033 void (*Callback)(int idx, void *client_data);
00034 void *client_data;
00035 event_owner_t *original_owner;
00036 event_owner_t new_owner;
00037 } socktimer_t;
00038
00039 static int socktimer_on_delete(void *client_data, int idx)
00040 {
00041 socktimer_t *data = client_data;
00042
00043 data->idx = -1;
00044 if (data->timerid >= 0) timer_destroy(data->timerid);
00045 else free(data);
00046 return 0;
00047 }
00048
00049 static int on_timer_delete(event_owner_t *owner, void *client_data)
00050 {
00051 socktimer_t *data = client_data;
00052
00053 if (data->original_owner && data->original_owner->on_delete) {
00054 data->original_owner->on_delete(data->original_owner, data->client_data);
00055 }
00056 data->timerid = -1;
00057 if (data->idx <= 0) free(data);
00058
00059 return 0;
00060 }
00061
00062 static int timer_callback(void *client_data)
00063 {
00064 socktimer_t *data = client_data;
00065
00066 if (!data->Callback) {
00067 sockbuf_delete(data->idx);
00068 return 0;
00069 }
00070
00071 data->Callback(data->idx, data->client_data);
00072 return 0;
00073 }
00074
00075 static sockbuf_filter_t socktimer_filter = {
00076 "socktimer",
00077 SOCKTIMER_LEVEL,
00078 NULL, NULL, NULL,
00079 NULL, NULL, NULL,
00080 NULL, socktimer_on_delete
00081 };
00082
00090 int socktimer_on(int idx, int timeout, int flags, void (*Callback)(int idx, void *cd), void *client_data, event_owner_t *owner)
00091 {
00092 egg_timeval_t timeval = {timeout, 0};
00093 socktimer_t *data;
00094
00095 if (!sockbuf_isvalid(idx)) return -1;
00096 if (!Callback) flags = 0;
00097 if (!sockbuf_get_filter_data(idx, &socktimer_filter, &data)) {
00098 if (data->timerid >= 0) timer_destroy(data->timerid);
00099 } else {
00100 data = malloc(sizeof(*data));
00101 sockbuf_attach_filter(idx, &socktimer_filter, data);
00102 }
00103
00104 data->idx = idx;
00105 data->timerflags = flags;
00106 data->Callback = Callback;
00107 data->client_data = client_data;
00108 data->original_owner = owner;
00109 data->new_owner = *owner;
00110 data->new_owner.on_delete = on_timer_delete;
00111 data->timerid = timer_create_complex(&timeval, "socktimer", timer_callback, data, flags, &data->new_owner);
00112
00113 return 0;
00114 }
00115
00125 int socktimer_off(int idx)
00126 {
00127 int ret;
00128 socktimer_t *data;
00129
00130 ret = sockbuf_detach_filter(idx, &socktimer_filter, &data);
00131 if (ret) return ret;
00132 if (data) {
00133 if (data->timerid >= 0) {
00134 timer_destroy(data->timerid);
00135 }
00136 free(data);
00137 }
00138 return 0;
00139 }
00140
00148 int socktimer_check(int idx)
00149 {
00150 if (!sockbuf_isvalid(idx)) return -1;
00151 return !sockbuf_get_filter_data(idx, &socktimer_filter, 0);
00152 }