// Thread-safe and non-blocking (may block if node needs to be allocated // from the operating system). Returns false if the freelist is not able to // allocate a new deque node. // Complexity: O(Processes) bool push_right(T const& data) { // Allocate the new node which we will be inserting. node* n = alloc_node(0, 0, data); if (n == 0) return false; // Loop until we insert successfully. while (true) { // Load the anchor. anchor_pair lrs = anchor_.lrs(); // Check if the deque is empty. // FIXME: Should we check both pointers here? if (lrs.get_right_ptr() == 0) { // If the deque is empty, we simply install a new anchor which // points to the new node as both its leftmost and rightmost // element. if (anchor_.cas(lrs, anchor_pair(n, n, lrs.get_left_tag(), lrs.get_right_tag() + 1))) return true; } // Check if the deque is stable. else if (lrs.get_left_tag() == stable) { // Make the left pointer on our new node refer to the current // rightmost node. n->left.store(node_pointer(lrs.get_right_ptr())); // Now we want to make the anchor point to our new node as the // leftmost node. We change the state to lpush as the deque // will become unstable if this operation succeeds. anchor_pair new_anchor(lrs.get_left_ptr(), n, rpush, lrs.get_right_tag() + 1); if (anchor_.cas(lrs, new_anchor)) { stabilize_right(new_anchor); return true; } } // The deque must be unstable, so we have to stabilize it before // we can continue. else // lrs.s() != stable stabilize(lrs); } }
void TextSelection::SetText (const char *text) { #define CONTENT_START (0) #define CONTENT_END ((guint32)-1) if (anchor.GetParent() == NULL || moving.GetParent() == NULL) // if either are null we're going nowhere fast... return; ClearSelection (); // at this point the selection is empty and anchor == moving if (text && *text) { if (anchor.GetParent()->Is (Type::RUN)) { const char *run_text = ((Run*)anchor.GetParent())->GetText(); if (run_text == NULL) run_text = "\0"; char *new_text = (char*)g_malloc0 (strlen (run_text) + strlen (text) + 1); if (strlen (text) < (size_t) anchor.ResolveLocation ()){ // #339RT enters here g_free (new_text); new_text = g_strdup ("BUGBUGBUG"); } else { strncpy (new_text, run_text, anchor.ResolveLocation()); strcpy (new_text + anchor.ResolveLocation(), text); strncpy (new_text + anchor.ResolveLocation() + strlen(text), run_text + anchor.ResolveLocation(), strlen (run_text) - anchor.ResolveLocation()); } ((Run*)anchor.GetParent())->SetText (new_text); if (moving.GetLocation() > strlen (new_text)) { anchor = TextPointer (anchor.GetParent(), CONTENT_END, anchor.GetLogicalDirection()); moving = TextPointer (anchor.GetParent(), CONTENT_END, anchor.GetLogicalDirection()); } else { TextPointer new_anchor (anchor.GetParent(), anchor.ResolveLocation () + strlen (text), anchor.GetLogicalDirection()); moving = TextPointer (anchor.GetParent(), anchor.ResolveLocation () + strlen (text), anchor.GetLogicalDirection()); anchor = new_anchor; } g_free (new_text); if (anchor.CompareTo_np (moving) < 0) { start = anchor; end = moving; } else { start = moving; end = anchor; } } else { IDocumentNode *node = anchor.GetParentNode(); DependencyObjectCollection *children = node->GetDocumentChildren(); if (!children) { // this can happen when anchor is in an InlineUIContainer. printf ("NIEX TextSelection.SetText for anchor == InlineUIContainer.\n"); return; } Run *r = MoonUnmanagedFactory::CreateRun (); r->SetText (text); if (children->Is(Type::BLOCK_COLLECTION)) { // the node takes Blocks as children, so we need to create a Paragraph first. Paragraph *p = MoonUnmanagedFactory::CreateParagraph(); children->Insert (anchor.GetLocation(), Value (p)); children = p->GetInlines(); children->Add (Value (r)); p->unref (); } else { children->Insert (anchor.GetLocation(), Value (r)); } anchor = TextPointer (r, CONTENT_END, anchor.GetLogicalDirection()); moving = TextPointer (r, CONTENT_END, anchor.GetLogicalDirection()); r->unref (); if (anchor.CompareTo_np (moving) < 0) { start = anchor; end = moving; } else { start = moving; end = anchor; } } } g_free (this->text); this->text = NULL; }