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; }
//! <b>Effects</b>: Moves the first n nodes starting at p to the end of the list. //! //! <b>Returns</b>: A pair containing the new first and last node of the list or //! if there has been any movement, a null pair if n leads to no movement. //! //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions. static std::pair<node_ptr, node_ptr> move_first_n_backwards(node_ptr p, std::size_t n) { std::pair<node_ptr, node_ptr> ret(node_ptr(0), node_ptr(0)); //Null shift, or count() == 0 or 1, nothing to do if(!n || !p || !NodeTraits::get_next(p)){ return ret; } node_ptr first = p; bool end_found = false; node_ptr new_last(0); node_ptr old_last(0); //Now find the new last node according to the shift count. //If we find 0 before finding the new last node //unlink p, shortcut the search now that we know the size of the list //and continue. for(std::size_t i = 1; i <= n; ++i){ new_last = first; first = NodeTraits::get_next(first); if(first == 0){ //Shortcut the shift with the modulo of the size of the list n %= i; if(!n) return ret; old_last = new_last; i = 0; //Unlink p and continue the new first node search first = p; //unlink_after(new_last); end_found = true; } } //If the p has not been found in the previous loop, find it //starting in the new first node and unlink it if(!end_found){ old_last = base_t::get_previous_node(first, node_ptr(0)); } //Now link p after the new last node NodeTraits::set_next(old_last, p); NodeTraits::set_next(new_last, node_ptr(0)); ret.first = first; ret.second = new_last; return ret; }
//! <b>Effects</b>: Moves the first n nodes starting at p to the beginning of the list. //! //! <b>Returns</b>: A pair containing the new first and last node of the list or //! if there has been any movement, a null pair if n leads to no movement. //! //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions. static std::pair<node_ptr, node_ptr> move_first_n_forward(node_ptr p, std::size_t n) { std::pair<node_ptr, node_ptr> ret(node_ptr(0), node_ptr(0)); //Null shift, or count() == 0 or 1, nothing to do if(!n || !p || !NodeTraits::get_next(p)) return ret; node_ptr first = p; //Iterate until p is found to know where the current last node is. //If the shift count is less than the size of the list, we can also obtain //the position of the new last node after the shift. node_ptr old_last(first), next_to_it, new_last(p); std::size_t distance = 1; while(!!(next_to_it = node_traits::get_next(old_last))){ if(distance++ > n) new_last = node_traits::get_next(new_last); old_last = next_to_it; } //If the shift was bigger or equal than the size, obtain the equivalent //forward shifts and find the new last node. if(distance <= n){ //Now find the equivalent forward shifts. //Shortcut the shift with the modulo of the size of the list std::size_t new_before_last_pos = (distance - (n % distance))% distance; //If the shift is a multiple of the size there is nothing to do if(!new_before_last_pos) return ret; for( new_last = p ; --new_before_last_pos ; new_last = node_traits::get_next(new_last)){ //empty } } //Get the first new node node_ptr new_first(node_traits::get_next(new_last)); //Now put the old beginning after the old end NodeTraits::set_next(old_last, p); NodeTraits::set_next(new_last, node_ptr(0)); ret.first = new_first; ret.second = new_last; return ret; }
//! <b>Effects</b>: Moves the node p n positions towards the end of the list. //! //! <b>Returns</b>: The previous node of p after the function if there has been any movement, //! Null if n leads to no movement. //! //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions. static node_ptr move_backwards(node_ptr p, std::size_t n) { //Null shift, nothing to do if(!n) return 0; node_ptr first = NodeTraits::get_next(p); //count() == 1 or 2, nothing to do if(NodeTraits::get_next(first) == p) return 0; bool end_found = false; node_ptr new_last(0); //Now find the new last node according to the shift count. //If we find p before finding the new last node //unlink p, shortcut the search now that we know the size of the list //and continue. for(std::size_t i = 1; i <= n; ++i){ new_last = first; first = NodeTraits::get_next(first); if(first == p){ //Shortcut the shift with the modulo of the size of the list n %= i; if(!n) return 0; i = 0; //Unlink p and continue the new first node search first = NodeTraits::get_next(p); base_t::unlink_after(new_last); end_found = true; } } //If the p has not been found in the previous loop, find it //starting in the new first node and unlink it if(!end_found){ base_t::unlink_after(base_t::get_previous_node(first, p)); } //Now link p after the new last node base_t::link_after(new_last, p); return new_last; }
//! <b>Effects</b>: Moves the node p n positions towards the beginning of the list. //! //! <b>Returns</b>: The previous node of p after the function if there has been any movement, //! Null if n leads equals to no movement. //! //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions. static node_ptr move_forward(node_ptr p, std::size_t n) { //Null shift, nothing to do if(!n) return 0; node_ptr first = node_traits::get_next(p); //count() == 1 or 2, nothing to do if(node_traits::get_next(first) == p) return 0; //Iterate until p is found to know where the current last node is. //If the shift count is less than the size of the list, we can also obtain //the position of the new last node after the shift. node_ptr old_last(first), next_to_it, new_last(p); std::size_t distance = 1; while(p != (next_to_it = node_traits::get_next(old_last))){ if(++distance > n) new_last = node_traits::get_next(new_last); old_last = next_to_it; } //If the shift was bigger or equal than the size, obtain the equivalent //forward shifts and find the new last node. if(distance <= n){ //Now find the equivalent forward shifts. //Shortcut the shift with the modulo of the size of the list std::size_t new_before_last_pos = (distance - (n % distance))% distance; //If the shift is a multiple of the size there is nothing to do if(!new_before_last_pos) return 0; for( new_last = p ; new_before_last_pos-- ; new_last = node_traits::get_next(new_last)){ //empty } } //Now unlink p and link it after the new last node base_t::unlink_after(old_last); base_t::link_after(new_last, p); return new_last; }