Esempio n. 1
0
void help_enq(wf_queue_head_t* queue, wf_queue_op_head_t* op_desc, int thread_id, int thread_to_help, long phase) {
	LOG_PROLOG();

	while (is_pending(op_desc, phase, thread_to_help)) {
		wf_queue_node_t *last = STAMPED_REF_TO_REF(queue->tail, wf_queue_node_t);
		stamped_ref_t *next = last->next;
		wf_queue_node_t* old_ref_next = STAMPED_REF_TO_REF(next, wf_queue_node_t);
		wf_queue_node_t *new_node = STAMPED_REF_TO_REF(*(op_desc->ref_mem.ops + thread_to_help), wf_queue_op_desc_t)->node;

		uint32_t old_stamp = last->next->stamp;
		uint32_t new_stamp = (old_stamp + 1);
		if (last == STAMPED_REF_TO_REF(queue->tail, wf_queue_node_t)) {
			if (STAMPED_REF_TO_REF(last->next, wf_queue_node_t) == NULL) {
				if (is_pending(op_desc, phase, thread_to_help)) {
					stamped_ref_t* node_new_stamped_ref = *(op_desc->ref_mem.next_reserve + thread_id);//(stamped_ref_t*)malloc(sizeof(stamped_ref_t));
					node_new_stamped_ref->ref = new_node;
					node_new_stamped_ref->stamp += new_stamp;
					if (CAS_COND1(STAMPED_REF_TO_REF(queue->tail, wf_queue_node_t)->next, next, old_ref_next, old_stamp, node_new_stamped_ref)) {
						if (CAS_COND2(STAMPED_REF_TO_REF(queue->tail, wf_queue_node_t)->next, next, old_ref_next, old_stamp, node_new_stamped_ref)) {
							help_finish_enq(queue, op_desc, thread_id);
							return;
						} else if (CAS_COND3(STAMPED_REF_TO_REF(queue->tail, wf_queue_node_t)->next, next, old_ref_next, old_stamp, node_new_stamped_ref)) {
							*(op_desc->ref_mem.next_reserve + thread_id) = next; // Recycle stamped reference
							help_finish_enq(queue, op_desc, thread_id);
							return;
						}
					}
				}
			} else {
				help_finish_enq(queue, op_desc, thread_id);
			}
		}
	}
	LOG_EPILOG();
}
Esempio n. 2
0
bool
MoveSCU
::_handle_main_association() const
{
    auto const response = this->_association->receive<message::CMoveResponse>();
    return !response.is_pending();
}
Esempio n. 3
0
void help_deq(wf_queue_head_t* queue, wf_queue_op_head_t* op_desc, int thread_id, int thread_to_help, long phase) {
	LOG_PROLOG();

	while (is_pending(op_desc, phase, thread_to_help)) {
		wf_queue_node_t *first = STAMPED_REF_TO_REF(queue->head, wf_queue_node_t);
		wf_queue_node_t *last = STAMPED_REF_TO_REF(queue->tail, wf_queue_node_t);
		wf_queue_node_t *next = STAMPED_REF_TO_REF(first->next, wf_queue_node_t);
		if (first == queue->head->ref) {
			if (first == last) {
				if (next == NULL) {
					stamped_ref_t* op_stamped_ref = *(op_desc->ref_mem.ops + thread_to_help);
					int old_stamp = op_stamped_ref->stamp;
					int new_stamp = old_stamp + 1;
					wf_queue_op_desc_t *op_old = STAMPED_REF_TO_REF(op_stamped_ref, wf_queue_op_desc_t);
					if ((last == queue->tail->ref) && is_pending(op_desc, phase, thread_to_help)) {
						wf_queue_op_desc_t* op_new = *(op_desc->ops_reserve + thread_id);//(wf_queue_op_desc_t*)malloc(sizeof(wf_queue_op_desc_t));
						op_new->phase = op_old->phase;
						op_new->enqueue = 0;
						op_new->pending = 0;
						op_new->node = NULL;
						stamped_ref_t* op_new_stamped_ref = *(op_desc->ref_mem.ops_reserve + thread_id);//(stamped_ref_t*)malloc(sizeof(stamped_ref_t));
						op_new_stamped_ref->ref = op_new;
						op_new_stamped_ref->stamp = new_stamp;
						if (CAS_COND1(*(op_desc->ref_mem.ops + thread_to_help), op_stamped_ref, op_old, old_stamp, op_new_stamped_ref)) {
							if (CAS_COND2(*(op_desc->ref_mem.ops + thread_to_help), op_stamped_ref, op_old, old_stamp, op_new_stamped_ref)) {
								// Nothing
							} else if (CAS_COND3(*(op_desc->ref_mem.ops + thread_to_help), op_stamped_ref, op_old, old_stamp, op_new_stamped_ref)) {
								*(op_desc->ops_reserve + thread_id) = op_old;
								*(op_desc->ref_mem.ops_reserve + thread_id) = op_stamped_ref;
							}
						}
					}
				} else {
					help_finish_enq(queue, op_desc, thread_id);
				}
			} else {
				stamped_ref_t* op_stamped_ref = *(op_desc->ref_mem.ops + thread_to_help);
				int old_stamp = op_stamped_ref->stamp;
				int new_stamp = old_stamp + 1;
				wf_queue_op_desc_t *op_old = STAMPED_REF_TO_REF(op_stamped_ref, wf_queue_op_desc_t);
				if (!is_pending(op_desc, phase, thread_to_help)) {
					break;
				}

				if (first == queue->head->ref && op_old->node != first) {
					wf_queue_op_desc_t* op_new = *(op_desc->ops_reserve + thread_id);
					op_new->phase = op_old->phase;
					op_new->enqueue = 0;
					op_new->pending = 1;
					op_new->node = first;
					stamped_ref_t* op_new_stamped_ref = *(op_desc->ref_mem.ops_reserve + thread_id);//(stamped_ref_t*)malloc(sizeof(stamped_ref_t));
					op_new_stamped_ref->ref = op_new;
					op_new_stamped_ref->stamp = new_stamp;
					if (CAS_COND1(*(op_desc->ref_mem.ops + thread_to_help), op_stamped_ref, op_old, old_stamp, op_new_stamped_ref)) {
						if (CAS_COND2(*(op_desc->ref_mem.ops + thread_to_help), op_stamped_ref, op_old, old_stamp, op_new_stamped_ref)) {
							// Nothing
						} else if (CAS_COND3(*(op_desc->ref_mem.ops + thread_to_help), op_stamped_ref, op_old, old_stamp, op_new_stamped_ref)) {
							*(op_desc->ops_reserve + thread_id) = op_old;
							*(op_desc->ref_mem.ops_reserve + thread_id) = op_stamped_ref;
						} else {
							continue;
						}
					} else {
						continue;
					}
				}

				compare_and_swap32(&(first->deq_tid), -1, thread_to_help);
				help_finish_deq(queue, op_desc, thread_id);
			}
		}
	}
	LOG_EPILOG();
}
bool t_presence_subscription::recv_notify(t_request *r, t_tuid tuid, t_tid tid) {
	if (t_subscription::recv_notify(r, tuid, tid)) return true;

	bool unsupported_body = false;
	
	// NOTE: if the subscription is still pending (RFC 3265 3.2.4), then the
	//       information in the body has no meaning.
	// NOTE: a NOTIFY request may have no body (RFC 3856 6.6.2)
	if (r->body && r->body->get_type() == BODY_PIDF_XML &&
	    !is_pending()) 
	{
		t_pidf_xml_body *body = dynamic_cast<t_pidf_xml_body *>(r->body);
		assert(body);
		
		string basic = body->get_basic_status();
		if (basic == PIDF_STATUS_BASIC_OPEN) {
			presence_state->set_basic_state(t_presence_state::ST_BASIC_OPEN);
		} else if (basic == PIDF_STATUS_BASIC_CLOSED) {
			presence_state->set_basic_state(t_presence_state::ST_BASIC_CLOSED);
		} else {
			log_file->write_header("t_presence_subscription::recv_notify",
				LOG_NORMAL, LOG_WARNING);
			log_file->write_raw("Unknown basic status in pidf: ");
			log_file->write_raw(basic);
			log_file->write_endl();
			log_file->write_footer();
			
			presence_state->set_basic_state(t_presence_state::ST_BASIC_UNKNOWN);
		}
	}
	
	// Verify if there is an usupported body.
	if (r->body && r->body->get_type() != BODY_PIDF_XML) {
		unsupported_body = true;
	}

	if (state == SS_TERMINATED) {
		if (may_resubscribe) {
			presence_state->set_basic_state(t_presence_state::ST_BASIC_UNKNOWN);
			log_file->write_report("Presence subscription terminated.",
				"t_presence_subscription::recv_notify");
		} else {
			if (reason_termination == EV_REASON_REJECTED) {
				presence_state->set_basic_state(t_presence_state::ST_BASIC_REJECTED);
				
				log_file->write_report("Presence agent rejected the subscription.",
					"t_presence_subscription::recv_notify");
			} else {
				// The PA ended the subscription and indicated
				// that resubscription is not possible. So no presence status
				// can be retrieved anymore. This should not happen.
				// Show it as a failure to the user.
				presence_state->set_failure_msg(reason_termination);
				presence_state->set_basic_state(t_presence_state::ST_BASIC_FAILED);
				
				log_file->write_report(
					"Presence agent permanently terminated the subscription.",
					"t_presence_subscription::recv_notify");
			}
		}
	}
	
	t_response *resp;
	if (unsupported_body) {
		resp = r->create_response(R_415_UNSUPPORTED_MEDIA_TYPE);
		SET_PRESENCE_HDR_ACCEPT(r->hdr_accept);
	} else {
		resp = r->create_response(R_200_OK);
	}
	send_response(user_config, resp, 0, tid);
	MEMMAN_DELETE(resp);
	delete resp;
	
	return true;
}
	bool			is_expired()		const throw()	{ return !is_pending();	}