static void remove_pipe(text *pipe_name, bool purge) { pipe *p; bool created; if (NULL != (p = find_pipe(pipe_name, &created, true))) { queue_item *q = p->items; while (q != NULL) { queue_item *aux_q; aux_q = q->next_item; if (q->ptr) ora_sfree(q->ptr); ora_sfree(q); q = aux_q; } p->items = NULL; p->size = 0; p->count = 0; if (!(purge && p->registered)) { ora_sfree(p->pipe_name); p->is_valid = false; } } }
static void unregister_event(int event_id, int sid) { alert_event *ev; int i; ev = &events[event_id]; if (ev->receivers_number > 0) { for (i = 0; i < ev->max_receivers; i++) { if (ev->receivers[i] == sid) { ev->receivers[i] = NOT_USED; ev->receivers_number -= 1; break; } } if (ev->receivers_number == 0) { ora_sfree(ev->receivers); ora_sfree(ev->event_name); ev->receivers = NULL; ev->event_name = NULL; } } }
static void* remove_first(pipe *p, bool *found) { struct _queue_item *q; void *ptr = NULL; *found = false; if (NULL != (q = p->items)) { p->count -= 1; ptr = q->ptr; p->items = q->next_item; *found = true; ora_sfree(q); if (p->items == NULL && !p->registered) { ora_sfree(p->pipe_name); p->is_valid = false; } } return ptr; }
static bool add_to_pipe(text *pipe_name, message_buffer *ptr, int limit, bool limit_is_valid) { pipe *p; bool created; bool result = false; message_buffer *sh_ptr; if (!ora_lock_shmem(SHMEMMSGSZ, MAX_PIPES, MAX_EVENTS, MAX_LOCKS,false)) return false; for (;;) { if (NULL != (p = find_pipe(pipe_name, &created, false))) { if (created) p->registered = ptr == NULL; if (limit_is_valid && (created || (p->limit < limit))) p->limit = limit; if (ptr != NULL) { if (NULL != (sh_ptr = ora_salloc(ptr->size))) { memcpy(sh_ptr,ptr,ptr->size); if (new_last(p, sh_ptr)) { p->size += ptr->size; result = true; break; } ora_sfree(sh_ptr); } if (created) { /* I created new pipe, but haven't memory for new value */ ora_sfree(p->pipe_name); p->is_valid = false; result = false; } } else result = true; } break; } LWLockRelease(shmem_lockid); return result; }
void* ora_srealloc(void *ptr, size_t size) { void *result; size_t aux_s = 0; int i; for (i = 0; i < *list_c; i++) if (list[i].first_byte_ptr == ptr) { if (align_size(size) <= list[i].size) return ptr; aux_s = list[i].size; } if (aux_s == 0) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("corrupted pointer"), errdetail("Failed while reallocating memory block in shared memory."), errhint("Report this bug to autors."))); if (NULL != (result = ora_salloc(size))) { memcpy(result, ptr, aux_s); ora_sfree(ptr); } return result; }
static message_buffer* get_from_pipe(text *pipe_name, bool *found) { pipe *p; bool created; message_buffer *shm_msg; message_buffer *result = NULL; if (!ora_lock_shmem(SHMEMMSGSZ, MAX_PIPES, MAX_EVENTS, MAX_LOCKS, false)) return NULL; if (NULL != (p = find_pipe(pipe_name, &created,false))) { if (!created) { if (NULL != (shm_msg = remove_first(p, found))) { p->size -= shm_msg->size; result = (message_buffer*) MemoryContextAlloc(TopMemoryContext, shm_msg->size); memcpy(result, shm_msg, shm_msg->size); ora_sfree(shm_msg); } } } LWLockRelease(shmem_lockid); return result; }
static void register_event(text *event_name) { alert_event *ev; int *new_receivers; int first_free; int i; find_lock(sid, true); ev = find_event(event_name, true, NULL); first_free = NOT_FOUND; for (i = 0; i < ev->max_receivers; i++) { if (ev->receivers[i] == sid) return; /* event is registered */ if (ev->receivers[i] == NOT_USED && first_free == NOT_FOUND) first_free = i; } /* * I can have a maximum of MAX_LOCKS receivers for one event. * Array receivers is increased for 16 fields */ if (first_free == NOT_FOUND) { if (ev->max_receivers + 16 > MAX_LOCKS) ereport(ERROR, (errcode(ERRCODE_ORA_PACKAGES_LOCK_REQUEST_ERROR), errmsg("lock request error"), errdetail("Failed to create session lock."), errhint("There are too many collaborating sessions. Increase MAX_LOCKS in 'pipe.h'."))); /* increase receiver's array */ new_receivers = (int*)salloc((ev->max_receivers + 16)*sizeof(int)); for (i = 0; i < ev->max_receivers + 16; i++) { if (i < ev->max_receivers) new_receivers[i] = ev->receivers[i]; else new_receivers[i] = NOT_USED; } ev->max_receivers += 16; if (ev->receivers) ora_sfree(ev->receivers); ev->receivers = new_receivers; first_free = ev->max_receivers - 16; } ev->receivers_number += 1; ev->receivers[first_free] = sid; }
static char* find_and_remove_message_item(int message_id, int sid, bool all, bool remove_all, bool filter_message, int *sleep, char **event_name) { alert_lock *alck; int _message_id; char *result = NULL; if (sleep != NULL) *sleep = 0; alck = find_lock(sid, false); if (event_name) *event_name = NULL; if (alck != NULL && alck->echo != NULL) { /* if I have registered and created item */ struct _message_echo *echo, *last_echo; echo = alck->echo; last_echo = NULL; while (echo != NULL) { char *message_text; bool destroy_msg_item = false; if (filter_message && echo->message_id != message_id) { last_echo = echo; echo = echo->next_echo; continue; } message_text = echo->message->message; _message_id = echo->message_id; if (!remove_receiver(echo->message, sid)) { destroy_msg_item = true; if (echo->message->prev_message != NULL) echo->message->prev_message->next_message = echo->message->next_message; else events[echo->message_id].messages = echo->message->next_message; if (echo->message->next_message != NULL) echo->message->next_message->prev_message = echo->message->prev_message; ora_sfree(echo->message->receivers); ora_sfree(echo->message); } if (last_echo == NULL) { alck->echo = echo->next_echo; ora_sfree(echo); echo = alck->echo; } else { last_echo->next_echo = echo->next_echo; ora_sfree(echo); echo = last_echo; } if (remove_all) { if (message_text != NULL && destroy_msg_item) ora_sfree(message_text); continue; } else if (_message_id == message_id || all) { /* I have to do local copy */ if (message_text) { result = pstrdup(message_text); if (destroy_msg_item) ora_sfree(message_text); } if (event_name != NULL) *event_name = pstrdup(events[_message_id].event_name); break; } } } return result; }