static int init_evt_srv(struct libxenvchan *ctrl, int domain, xentoollog_logger *logger) { evtchn_port_or_error_t port; ctrl->event = xc_evtchn_open(logger, 0); if (!ctrl->event) return -1; port = xc_evtchn_bind_unbound_port(ctrl->event, domain); if (port < 0) goto fail; ctrl->event_port = port; if (xc_evtchn_unmask(ctrl->event, ctrl->event_port)) goto fail; return 0; fail: if (port >= 0) xc_evtchn_unbind(ctrl->event, port); xc_evtchn_close(ctrl->event); ctrl->event = NULL; return -1; }
CAMLprim value stub_eventchn_bind_unbound_port(value xce, value remote_domid) { evtchn_port_or_error_t rc; rc = xc_evtchn_bind_unbound_port(_H(xce), Int_val(remote_domid)); if (rc == -1) caml_failwith("evtchn bind_unbound_port failed"); return Val_int(rc); }
CAMLprim value stub_eventchn_bind_unbound_port(value xce, value remote_domid) { CAMLparam2(xce, remote_domid); evtchn_port_or_error_t rc; rc = xc_evtchn_bind_unbound_port(_H(xce), Int_val(remote_domid)); if (rc == -1) { perror("xc_evtchn_bind_unbound_port"); caml_failwith(strerror(errno)); } CAMLreturn(Val_int(rc)); }
ivc_connection_t *acceptConnection(libIVC_t *iface, char *name, ivc_contype_t type, uint32_t num_pages, float per) { char *key, *val, *domStr = NULL; uint32_t me, other, *gs, ps; unsigned int len; void *buffer; /* we can only do this if we create grant references */ if(!iface->gs) return NULL; /* other <- read `fmap` waitForKey xs (targetPath ++ "/LeftDomId) */ ASPRINTF(&key, "/rendezvous/%s/LeftDomId", name); while(!domStr) { domStr = xs_read(iface->xs, 0, key, &len); } sscanf(domStr, "dom%d", &other); /* me <- xsGetDomId */ me = getMyDomId(iface); /* (gs, ps, confirm) <- makeConnection other extra */ gs = calloc(num_pages, sizeof(uint32_t)); buffer = xc_gntshr_share_pages(iface->gs, other, num_pages, gs, 1); assert(buffer); ps = xc_evtchn_bind_unbound_port(iface->ec, other); assert(ps); /* xsWrite xs (targetPath ++ "/RightDomId") (show me) */ free(key), ASPRINTF(&key, "/rendezvous/%s/RightDomId", name); free(val), ASPRINTF(&val, "dom%d", me); xs_write(iface->xs, 0, key, val, strlen(val)); /* xsWrite xs (targetPath ++ "/RightGrantRefs") (show gs) */ free(key), ASPRINTF(&key, "/rendezvous/%s/RightGrantRefs", name); free(val), val = showGrantRefList(gs, num_pages); xs_write(iface->xs, 0, key, val, strlen(val)); /* xsWrite xs (targetPath ++ "/RightPorts") (show ps) */ free(key), ASPRINTF(&key, "/rendezvous/%s/RightPorts", name); free(val), ASPRINTF(&val, "[echan:%d]", ps); xs_write(iface->xs, 0, key, val, strlen(val)); /* _ <- waitForKey xs (targetPath ++ "/LeftConnectionConfirmed") */ free(key), ASPRINTF(&key, "/rendezvous/%s/LeftConnectionConfirmed", name); free(val), val = NULL; while(!val) { val = xs_read(iface->xs, 0, key, &len); } /* removePath xs targetPath */ free(key), ASPRINTF(&key, "/rendezvous/%s", name); xs_rm(iface->xs, 0, key); /* confirm */ return buildChannel(iface, other, type, ps, buffer, 4096 * num_pages, per, 1); }
int pa__init(pa_module*m) { struct userdata *u; pa_modargs *ma; pa_sink_new_data data; int backend_state; int ret; char strbuf[100]; pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments."); goto fail; } ss = m->core->default_sample_spec; map = m->core->default_channel_map; /* user arguments override these */ if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { pa_log("Invalid sample format specification or channel map"); return 1; } /* Xen Basic init */ xsh = xs_domain_open(); if (xsh==NULL) { pa_log("xs_domain_open failed"); goto fail; } set_state(XenbusStateUnknown); xch = xc_interface_open(NULL, NULL, 0); if (xch==0) { pa_log("xc_interface_open failed"); goto fail; } xce = xc_evtchn_open(NULL, 0); if (xce==0) { pa_log("xc_evtchn_open failed"); goto fail; } /* use only dom0 as the backend for now */ xen_evtchn_port = xc_evtchn_bind_unbound_port(xce, 0); if (xen_evtchn_port == 0) { pa_log("xc_evtchn_bind_unbound_port failed"); } /* get grant reference & map locally */ if (alloc_gref(&gref, (void**)&ioring)) { pa_log("alloc_gref failed"); }; device_id = 0; /* hardcoded for now */ if (register_backend_state_watch()) { pa_log("Xen sink: register xenstore watch failed"); }; publish_param_int("event-channel", xen_evtchn_port); publish_param_int("ring-ref", gref.gref_ids[0]); /* let's ask for something absurd and deal with rejection */ ss.rate = 192000; publish_spec(&ss); ret=0; while (!ret) { backend_state = wait_for_backend_state_change(); if (backend_state == STATE_UNDEFINED) { pa_log("Xen Backend is taking long to respond, still waiting..."); continue; } else if (backend_state == -1) { pa_log("Error while waiting for backend: %s", strerror(errno)); break; goto fail; } ret = state_callbacks[backend_state](); } if (ret!=NEGOTIATION_OK) { pa_log("Negotiation with Xen backend failed!"); return 1; } pa_sample_spec_snprint(strbuf, 100, &ss); pa_log_debug("Negotiation ended, the result was: %s", strbuf); /* End of Phase 2, begin playback cycle */ u = pa_xnew0(struct userdata, 1); u->core = m->core; u->module = m; m->userdata = u; pa_memchunk_reset(&u->memchunk); u->rtpoll = pa_rtpoll_new(); pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll); u->write_type = 0; /* init ring buffer */ ioring->prod_indx = ioring->cons_indx = 0; ioring->usable_buffer_space = BUFSIZE - BUFSIZE % pa_frame_size(&ss); pa_sink_new_data_init(&data); data.driver = __FILE__; data.module = m; pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME)); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, "xensink"); pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Xen PV audio sink"); pa_sink_new_data_set_sample_spec(&data, &ss); pa_sink_new_data_set_channel_map(&data, &map); if (pa_modargs_get_proplist(ma, "sink_properties", data.proplist, PA_UPDATE_REPLACE) < 0) { pa_log("Invalid properties"); pa_sink_new_data_done(&data); goto fail; } u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY); pa_sink_new_data_done(&data); if (!u->sink) { pa_log("Failed to create sink."); goto fail; } u->sink->parent.process_msg = sink_process_msg; u->sink->userdata = u; pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); pa_sink_set_rtpoll(u->sink, u->rtpoll); pa_sink_set_max_request(u->sink, ioring->usable_buffer_space); pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(ioring->usable_buffer_space, &u->sink->sample_spec)); u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1); if (!(u->thread = pa_thread_new("xenpv-sink", thread_func, u))) { pa_log("Failed to create thread."); goto fail; } pa_sink_put(u->sink); pa_modargs_free(ma); return 0; fail: if (ma) pa_modargs_free(ma); pa__done(m); return -1; }