nckernel  0.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ston.c
Go to the documentation of this file.
1 #include <sys/types.h>
2 #include <stddef.h>
3 #include <stdint.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <errno.h>
8 
9 #include <list.h>
10 #include <ston.h>
11 
12 struct ston_item {
13  struct list_head head;
14 
15  const void *key; /* 오브젝트 아이디 */
16  void *obj; /* 생성된 오브젝트 */
17  int refcnt; /* 오브젝트 참조 개수 */
18 };
19 
20 struct ston {
21  struct list_head items;
22 
23  struct ston_ops ops; /* 오브젝트 연산자: 생성, 소멸 관리 */
24 };
25 
26 struct ston *ston_init(struct ston_ops *ops)
27 {
28  struct ston *ston;
29 
30  ston = malloc(sizeof(*ston));
31  if (!ston) {
32  return NULL;
33  }
34 
35  memcpy(&ston->ops, ops, sizeof(*ops));
36  INIT_LIST_HEAD(&ston->items);
37 
38  return ston;
39 }
40 
41 int ston_fini(struct ston *ston)
42 {
43  struct list_head *pos;
44  struct list_head *n;
45  struct ston_item *item;
46 
47  list_for_each_safe(pos, n, &ston->items) {
48  item = list_entry(pos, struct ston_item, head);
49  list_del(pos);
50 
51  ston->ops.destroy(item->obj);
52  free(item);
53  }
54 
55  free(ston);
56  return 0;
57 }
58 
59 static int default_compare(const void *key_a, const void *key_b)
60 {
61  return (uint32_t)key_a != (uint32_t)key_b;
62 }
63 
64 static inline struct ston_item *find_item(struct ston *ston, const void *key)
65 {
66  struct ston_item *item;
67  struct list_head *pos;
68  int (*compare)(const void *key_a, const void *key_b);
69 
70  compare = ston->ops.compare ? ston->ops.compare : default_compare;
71 
72  list_for_each(pos, &ston->items) {
73  item = list_entry(pos, struct ston_item, head);
74 
75  if (!compare(item->key, key)) {
76  return item;
77  }
78  }
79 
80  return NULL;
81 }
82 
83 static inline struct ston_item *find_item_obj(struct ston *ston, void *obj)
84 {
85  struct ston_item *item;
86  struct list_head *pos;
87 
88  list_for_each(pos, &ston->items) {
89  item = list_entry(pos, struct ston_item, head);
90 
91  if (item->obj == obj) {
92  return item;
93  }
94  }
95 
96  return NULL;
97 }
98 
99 void *ston_create(struct ston *ston, const void *key)
100 {
101  struct ston_item *item;
102 
103  item = find_item(ston, key);
104  if (item) {
105  return item->obj;
106  }
107 
108  item = malloc(sizeof(*item));
109  if (!item) {
110  return NULL;
111  }
112 
113  item->key = key;
114  item->refcnt = 1;
115  item->obj = ston->ops.create(key);
116 
117  list_add_tail(&item->head, &ston->items);
118  return item->obj;
119 }
120 
121 int ston_destroy(struct ston *ston, void *obj)
122 {
123  struct ston_item *item;
124  int (*destroy)(void *item);
125 
126  item = find_item_obj(ston, obj);
127  if (!item) {
128  return -ENOENT;
129  }
130 
131  item->refcnt--;
132  if (item->refcnt > 0) {
133  return 0;
134  }
135 
136  destroy = ston->ops.destroy;
137  list_del(&item->head);
138  free(item);
139 
140  return destroy(obj);
141 }
142 
143 /* End of a file */