| 139 | } |
| 140 | |
| 141 | struct struct_hist *_sh_push(void *obj, struct struct_hist_list *list, int refs, |
| 142 | osips_malloc_f malloc_f, osips_free_f free_f) |
| 143 | { |
| 144 | struct struct_hist *sh, *last; |
| 145 | |
| 146 | if (!list) |
| 147 | return NULL; |
| 148 | |
| 149 | sh = func_malloc(malloc_f, sizeof *sh); |
| 150 | if (!sh) { |
| 151 | LM_ERR("oom\n"); |
| 152 | return NULL; |
| 153 | } |
| 154 | /* CAREFUL: sh is not memset, for speed reasons! */ |
| 155 | |
| 156 | sh->actions = func_malloc(malloc_f, list->init_actions_sz * sizeof *sh->actions); |
| 157 | if (!sh->actions) { |
| 158 | LM_ERR("oom2\n"); |
| 159 | func_free(free_f, sh); |
| 160 | return NULL; |
| 161 | } |
| 162 | /* CAREFUL: sh->actions is not memset, for speed reasons! */ |
| 163 | |
| 164 | sh->obj = obj; |
| 165 | sh->obj_name = list->obj_name; |
| 166 | sh->created = get_uticks(); |
| 167 | sh->shlist = list; |
| 168 | sh->ref = 1 + refs; /* one for "list", the rest are for the caller */ |
| 169 | sh->len = 0; |
| 170 | sh->max_len = list->init_actions_sz; |
| 171 | sh->flush_offset = 0; |
| 172 | sh->auto_logging = list->auto_logging; |
| 173 | |
| 174 | lock_init(&sh->wlock); |
| 175 | |
| 176 | lock_get(&list->wlock); |
| 177 | list_add(&sh->list, &list->objects); |
| 178 | list->total_obj++; |
| 179 | list->len++; |
| 180 | |
| 181 | if (list->win_sz && list->len > list->win_sz) { |
| 182 | last = list_entry(list->objects.prev, struct struct_hist, list); |
| 183 | list_del(&last->list); |
| 184 | INIT_LIST_HEAD(&last->list); |
| 185 | list->len--; |
| 186 | sh_unref_unsafe(last, free_f); |
| 187 | } |
| 188 | lock_release(&list->wlock); |
| 189 | |
| 190 | return sh; |
| 191 | } |
| 192 | |
| 193 | static void sh_free(struct struct_hist *sh, osips_free_f free_f) |
| 194 | { |
nothing calls this directly
no test coverage detected