]> git.lizzy.rs Git - dragonstd.git/blob - map.c
61e971cd24368098a86fbefb1b4076550c2b5b2e
[dragonstd.git] / map.c
1 #include "map.h"
2
3 static bool get_lock(Map *map, bool write)
4 {
5         bool success;
6
7         pthread_rwlock_rdlock(&map->clk);
8
9         if ((success = ! map->cnl)) {
10                 if (write)
11                         pthread_rwlock_wrlock(&map->tlk);
12                 else
13                         pthread_rwlock_rdlock(&map->tlk);
14         }
15
16         pthread_rwlock_unlock(&map->clk);
17
18         return success;
19 }
20
21 void map_ini(Map *map)
22 {
23         tree_ini(&map->tre);
24         pthread_rwlock_init(&map->tlk, NULL);
25         map->cnl = false;
26         pthread_rwlock_init(&map->clk, NULL);
27 }
28
29 void map_dst(Map *map)
30 {
31         pthread_rwlock_destroy(&map->tlk);
32         pthread_rwlock_destroy(&map->clk);
33 }
34
35 void map_cnl(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order)
36 {
37         pthread_rwlock_wrlock(&map->clk);
38         map->cnl = true;
39
40         pthread_rwlock_wrlock(&map->tlk);
41         pthread_rwlock_unlock(&map->clk);
42
43         tree_clr(&map->tre, iter, arg, trans, order);
44
45         pthread_rwlock_unlock(&map->tlk);
46 }
47
48 #define WRAP_TREE_FUNC(name, write) \
49         void *map_ ## name(Map *map, void *dat, Comparator cmp, Transformer trans) \
50         { \
51                 if (! get_lock(map, write)) \
52                         return NULL; \
53  \
54                 dat = tree_ ## name(&map->tre, dat, cmp, trans); \
55                 pthread_rwlock_unlock(&map->tlk); \
56                 return dat; \
57         }
58
59 WRAP_TREE_FUNC(add, true)
60 WRAP_TREE_FUNC(get, false)
61 WRAP_TREE_FUNC(del, true)
62
63 void map_trv(Map *map, Iterator iter, void *arg, Transformer trans, TreeTraversionOrder order)
64 {
65         if (! get_lock(map, false))
66                 return;
67
68         tree_trv(&map->tre, iter, arg, trans, order);
69         pthread_rwlock_unlock(&map->tlk);
70 }