void capops_retrieve(struct domcapref cap, move_result_handler_t result_handler, void *st) { errval_t err; distcap_state_t state; err = dom_cnode_get_state(cap, &state); GOTO_IF_ERR(err, report_error); if (distcap_state_is_busy(state)) { err = MON_ERR_REMOTE_CAP_RETRY; } if (distcap_state_is_foreign(state)) { err = MON_ERR_CAP_FOREIGN; } GOTO_IF_ERR(err, report_error); err = monitor_lock_cap(cap.croot, cap.cptr, cap.bits); GOTO_IF_ERR(err, report_error); struct retrieve_rpc_st *rst = NULL; err = calloce(1, sizeof(*rst), &rst); GOTO_IF_ERR(err, unlock_cap); rst->cap = cap; rst->result_handler = result_handler; rst->st = st; err = monitor_get_domcap_owner(cap, &rst->prev_owner); GOTO_IF_ERR(err, free_st); if (rst->prev_owner == my_core_id) { err = SYS_ERR_OK; goto free_st; } retrieve_owner__enq(rst); return; free_st: free(rst); unlock_cap: caplock_unlock(cap); report_error: result_handler(err, st); }
errval_t capsend_owner(struct domcapref capref, struct msg_queue_elem *queue_elem) { errval_t err; // read cap owner coreid_t owner; err = monitor_get_domcap_owner(capref, &owner); if (err_is_fail(err)) { return err; } // enqueue to owner return capsend_target(owner, queue_elem); }