Dolda2000 GitWeb
/
doldaconnect.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fix some potential issues when freeing running cbchains.
[doldaconnect.git]
/
include
/
utils.h
diff --git
a/include/utils.h
b/include/utils.h
index
5c50dd4
..
4eada80
100644
(file)
--- a/
include/utils.h
+++ b/
include/utils.h
@@
-22,6
+22,7
@@
#include <stdarg.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdarg.h>
#include <stdlib.h>
#include <malloc.h>
+#include <assert.h>
#ifdef DAEMON
#include "log.h"
#endif
#ifdef DAEMON
#include "log.h"
#endif
@@
-54,6
+55,7
@@
struct cbchain_ ## name { \
int (*func)(args, void *data); \
void (*destroy)(void *data); \
void *data; \
int (*func)(args, void *data); \
void (*destroy)(void *data); \
void *data; \
+ int running, free; \
} * name
#define GCBCHAIN(name, args...) \
} * name
#define GCBCHAIN(name, args...) \
@@
-129,6
+131,7
@@
do { \
do { \
struct cbchain_ ## name *__new_cb__; \
__new_cb__ = smalloc(sizeof(*__new_cb__)); \
do { \
struct cbchain_ ## name *__new_cb__; \
__new_cb__ = smalloc(sizeof(*__new_cb__)); \
+ __new_cb__->running = __new_cb__->free = 0; \
__new_cb__->func = funca; \
__new_cb__->destroy = destroya; \
__new_cb__->data = dataa; \
__new_cb__->func = funca; \
__new_cb__->destroy = destroya; \
__new_cb__->data = dataa; \
@@
-140,11
+143,12
@@
do { \
(obj)->name = __new_cb__; \
} while(0)
(obj)->name = __new_cb__; \
} while(0)
-#define CBUNREG(obj, name, dataa) \
-
do
{ \
+#define CBUNREG(obj, name,
funca,
dataa) \
+
(
{ \
struct cbchain_ ## name *__cur__; \
struct cbchain_ ## name *__cur__; \
+ int __found__ = 0; \
for(__cur__ = (obj)->name; __cur__ != NULL; __cur__ = __cur__->next) { \
for(__cur__ = (obj)->name; __cur__ != NULL; __cur__ = __cur__->next) { \
- if(
__cur__->data == (dataa
)) { \
+ if(
((void *)(__cur__->func) == (void *)(funca)) && (__cur__->data == (void *)(dataa)
)) { \
if(__cur__->destroy != NULL) \
__cur__->destroy(__cur__->data); \
if(__cur__->prev != NULL) \
if(__cur__->destroy != NULL) \
__cur__->destroy(__cur__->data); \
if(__cur__->prev != NULL) \
@@
-154,10
+158,11
@@
do { \
if(__cur__ == (obj)->name) \
(obj)->name = __cur__->next; \
free(__cur__); \
if(__cur__ == (obj)->name) \
(obj)->name = __cur__->next; \
free(__cur__); \
+ __found__ = 1; \
break; \
} \
} \
break; \
} \
} \
-
} while(0
)
+
__found__;}
)
#define GCBREG(name, funca, dataa) \
do { \
#define GCBREG(name, funca, dataa) \
do { \
@@
-180,18
+185,30
@@
do { \
struct cbchain_ ## name *__cur__; \
while((__cur__ = (obj)->name) != NULL) { \
(obj)->name = __cur__->next; \
struct cbchain_ ## name *__cur__; \
while((__cur__ = (obj)->name) != NULL) { \
(obj)->name = __cur__->next; \
- if(__cur__->destroy != NULL) \
- __cur__->destroy(__cur__->data); \
- free(__cur__); \
+ if(__cur__->running) { \
+ __cur__->free = 1; \
+ } else { \
+ if(__cur__->destroy != NULL) \
+ __cur__->destroy(__cur__->data); \
+ free(__cur__); \
+ } \
} \
} while(0)
#define CBCHAINDOCB(obj, name, args...) \
do { \
struct cbchain_ ## name *__cur__, *__next__; \
} \
} while(0)
#define CBCHAINDOCB(obj, name, args...) \
do { \
struct cbchain_ ## name *__cur__, *__next__; \
+ int __res__; \
for(__cur__ = (obj)->name; __cur__ != NULL; __cur__ = __next__) { \
__next__ = __cur__->next; \
for(__cur__ = (obj)->name; __cur__ != NULL; __cur__ = __next__) { \
__next__ = __cur__->next; \
- if(__cur__->func(args, __cur__->data)) { \
+ __cur__->running = 1; \
+ __res__ = __cur__->func(args, __cur__->data); \
+ __cur__->running = 0; \
+ if(__cur__->free) { \
+ free(__cur__); \
+ break; \
+ } \
+ if(__res__) { \
if(__cur__->next != NULL) \
__cur__->next->prev = __cur__->prev; \
if(__cur__->prev != NULL) \
if(__cur__->next != NULL) \
__cur__->next->prev = __cur__->prev; \
if(__cur__->prev != NULL) \