/** * Instantiate a downloader * * @v job Job control interface * @v image Image to fill with downloaded file * @v type Location type to pass to xfer_open() * @v ... Remaining arguments to pass to xfer_open() * @ret rc Return status code * * Instantiates a downloader object to download the specified URI into * the specified image object. */ int create_downloader ( struct interface *job, struct image *image, int type, ... ) { struct downloader *downloader; va_list args; int rc; /* Allocate and initialise structure */ downloader = zalloc ( sizeof ( *downloader ) ); if ( ! downloader ) return -ENOMEM; ref_init ( &downloader->refcnt, downloader_free ); intf_init ( &downloader->job, &downloader_job_desc, &downloader->refcnt ); intf_init ( &downloader->xfer, &downloader_xfer_desc, &downloader->refcnt ); downloader->image = image_get ( image ); va_start ( args, type ); /* Instantiate child objects and attach to our interfaces */ if ( ( rc = xfer_vopen ( &downloader->xfer, type, args ) ) != 0 ) goto err; /* Attach parent interface, mortalise self, and return */ intf_plug_plug ( &downloader->job, job ); ref_put ( &downloader->refcnt ); va_end ( args ); return 0; err: downloader_finished ( downloader, rc ); ref_put ( &downloader->refcnt ); va_end ( args ); return rc; }
/** * Described in header. */ void libimcv_deinit(void) { if (ref_put(&libimcv_ref)) { imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_IETF); imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_ITA); DESTROY_IF(imcv_pa_tnc_attributes); DBG1(DBG_LIB, "libimcv terminated"); } if (ref_put(&libstrongswan_ref)) { library_deinit(); } }
static int numeric_resolv ( struct interface *resolv, const char *name, struct sockaddr *sa ) { struct numeric_resolv *numeric; struct sockaddr_in *sin; /* Allocate and initialise structure */ numeric = zalloc ( sizeof ( *numeric ) ); if ( ! numeric ) return -ENOMEM; ref_init ( &numeric->refcnt, NULL ); intf_init ( &numeric->resolv, &null_intf_desc, &numeric->refcnt ); process_init ( &numeric->process, &numeric_process_desc, &numeric->refcnt ); memcpy ( &numeric->sa, sa, sizeof ( numeric->sa ) ); DBGC ( numeric, "NUMERIC %p attempting to resolve \"%s\"\n", numeric, name ); /* Attempt to resolve name */ sin = ( ( struct sockaddr_in * ) &numeric->sa ); if ( inet_aton ( name, &sin->sin_addr ) != 0 ) { sin->sin_family = AF_INET; } else { numeric->rc = -EINVAL; } /* Attach to parent interface, mortalise self, and return */ intf_plug_plug ( &numeric->resolv, resolv ); ref_put ( &numeric->refcnt ); return 0; }
/** * Handle expired timer * * @v timer Retry timer */ static void timer_expired ( struct retry_timer *timer ) { int fail; /* Stop timer without performing RTT calculations */ DBG2 ( "Timer %p stopped at time %ld on expiry\n", timer, currticks() ); assert ( timer->running ); list_del ( &timer->list ); timer->running = 0; timer->count++; /* Back off the timeout value */ timer->timeout <<= 1; if ( timer->max_timeout == 0 ) /* 0 means "use default timeout" */ timer->max_timeout = DEFAULT_MAX_TIMEOUT; if ( ( fail = ( timer->timeout > timer->max_timeout ) ) ) timer->timeout = timer->max_timeout; DBG ( "Timer %p timeout backed off to %ld\n", timer, timer->timeout ); /* Call expiry callback */ timer->expired ( timer, fail ); ref_put ( timer->refcnt ); }
/** * Remove ACPI descriptor * * @v desc ACPI descriptor */ void acpi_del ( struct acpi_descriptor *desc ) { /* Remove from list of descriptors */ list_check_contains_entry ( desc, &desc->model->descs, list ); list_del ( &desc->list ); ref_put ( desc->refcnt ); }
int rb_vertex_array_ref_put(struct rb_vertex_array* array) { if(!array) return -1; ref_put(&array->ref, release_vertex_array); return 0; }
enum edit_error edit_picking_ref_put(struct edit_picking* picking) { if(UNLIKELY(!picking)) return EDIT_INVALID_ARGUMENT; ref_put(&picking->ref, release_picking); return EDIT_NO_ERROR; }
int rb_context_ref_put(struct rb_context* ctxt) { if(!ctxt) return -1; ref_put(&ctxt->ref, release_context); return 0; }
int rb_uniform_ref_put(struct rb_uniform* uniform) { if(!uniform) return -1; ref_put(&uniform->ref, release_uniform); return 0; }
/** * Shut down CMRC connection gracefully * * @v cmrc Communication-Managed Reliable Connection * * The Infiniband data structures are not reference-counted or * guarded. It is therefore unsafe to shut them down while we may be * in the middle of a callback from the Infiniband stack (e.g. in a * receive completion handler). * * This shutdown process will run some time after the call to * ib_cmrc_close(), after control has returned out of the Infiniband * core, and will shut down the Infiniband interfaces cleanly. * * The shutdown process holds an implicit reference on the CMRC * connection, ensuring that the structure is not freed before the * shutdown process has run. */ static void ib_cmrc_shutdown ( struct ib_cmrc_connection *cmrc ) { DBGC ( cmrc, "CMRC %p shutting down\n", cmrc ); /* Shut down Infiniband interface */ ib_destroy_conn ( cmrc->ibdev, cmrc->qp, cmrc->conn ); ib_destroy_qp ( cmrc->ibdev, cmrc->qp ); ib_destroy_cq ( cmrc->ibdev, cmrc->cq ); ib_close ( cmrc->ibdev ); /* Drop the remaining reference */ ref_put ( &cmrc->refcnt ); }
/** * Described in header. */ void libimcv_deinit(void) { if (ref_put(&libimcv_ref)) { imcv_pts_components->remove_vendor(imcv_pts_components, PEN_TCG); imcv_pts_components->remove_vendor(imcv_pts_components, PEN_ITA); imcv_pts_components->destroy(imcv_pts_components); imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_IETF); imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_ITA); imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_TCG); DESTROY_IF(imcv_pa_tnc_attributes); imcv_pa_tnc_attributes = NULL; DESTROY_IF(imcv_db); DESTROY_IF(imcv_sessions); DBG1(DBG_LIB, "libimcv terminated"); } if (ref_put(&libstrongswan_ref)) { library_deinit(); } }
static void release_picking(struct ref* ref) { struct edit_picking* picking = NULL; assert(ref); picking = CONTAINER_OF(ref, struct edit_picking, ref); EDIT(imgui_ref_put(picking->imgui)); EDIT(model_instance_selection_ref_put(picking->instance_selection)); APP(ref_put(picking->app)); SL(free_hash_table(picking->picked_instances_htbl)); MEM_FREE(picking->allocator, picking); }
/** * Create ELS response * * @v xchg Exchange interface * @v port Fibre Channel port * @v port_id Local port ID * @v peer_port_id Peer port ID * @ret rc Return status code */ static int fc_els_respond ( struct interface *xchg, struct fc_port *port, struct fc_port_id *port_id, struct fc_port_id *peer_port_id ) { struct fc_els *els; /* Allocate and initialise structure */ els = fc_els_create ( port, port_id, peer_port_id ); if ( ! els ) return -ENOMEM; /* Attach to exchange interface, mortalise self, and return */ intf_plug_plug ( &els->xchg, xchg ); ref_put ( &els->refcnt ); return 0; }
/** * Start name resolution * * @v resolv Name resolution interface * @v name Name to resolve * @v sa Socket address to complete * @ret rc Return status code */ int resolv ( struct interface *resolv, const char *name, struct sockaddr *sa ) { struct resolv_mux *mux; size_t name_len = ( strlen ( name ) + 1 ); int rc; /* Allocate and initialise structure */ mux = zalloc ( sizeof ( *mux ) + name_len ); if ( ! mux ) return -ENOMEM; ref_init ( &mux->refcnt, NULL ); intf_init ( &mux->parent, &null_intf_desc, &mux->refcnt ); intf_init ( &mux->child, &resmux_child_desc, &mux->refcnt ); mux->resolver = table_start ( RESOLVERS ); if ( sa ) memcpy ( &mux->sa, sa, sizeof ( mux->sa ) ); memcpy ( mux->name, name, name_len ); DBGC ( mux, "RESOLV %p attempting to resolve \"%s\"\n", mux, name ); /* Start first resolver in chain. There will always be at * least one resolver (the numeric resolver), so no need to * check for the zero-resolvers-available case. */ if ( ( rc = resmux_try ( mux ) ) != 0 ) goto err; /* Attach parent interface, mortalise self, and return */ intf_plug_plug ( &mux->parent, resolv ); ref_put ( &mux->refcnt ); return 0; err: ref_put ( &mux->refcnt ); return rc; }
/** * Described in header. */ void libpts_deinit(void) { if (ref_put(&libpts_ref)) { pts_components->remove_vendor(pts_components, PEN_TCG); pts_components->remove_vendor(pts_components, PEN_ITA); pts_components->destroy(pts_components); if (!imcv_pa_tnc_attributes) { return; } imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_TCG); DBG1(DBG_LIB, "libpts terminated"); } }
/** * Create ELS request * * @v job Parent job-control interface * @v port Fibre Channel port * @v peer_port_id Peer port ID * @v handler ELS handler * @ret rc Return status code */ int fc_els_request ( struct interface *job, struct fc_port *port, struct fc_port_id *peer_port_id, struct fc_els_handler *handler ) { struct fc_els *els; /* Allocate and initialise structure */ els = fc_els_create ( port, &port->port_id, peer_port_id ); if ( ! els ) return -ENOMEM; els->handler = handler; els->flags = FC_ELS_REQUEST; process_add ( &els->process ); /* Attach to parent job interface, mortalise self, and return */ intf_plug_plug ( &els->job, job ); ref_put ( &els->refcnt ); return 0; }
/** * Stop timer * * @v timer Retry timer * * This stops the timer and updates the timer's timeout value. */ void stop_timer ( struct retry_timer *timer ) { unsigned long old_timeout = timer->timeout; unsigned long now = currticks(); unsigned long runtime; /* If timer was already stopped, do nothing */ if ( ! timer->running ) return; list_del ( &timer->list ); runtime = ( now - timer->start ); timer->running = 0; DBG2 ( "Timer %p stopped at time %ld (ran for %ld)\n", timer, now, runtime ); /* Update timer. Variables are: * * r = round-trip time estimate (i.e. runtime) * t = timeout value (i.e. timer->timeout) * s = smoothed round-trip time * * By choice, we set t = 4s, i.e. allow for four times the * normal round-trip time to pass before retransmitting. * * We want to smooth according to s := ( 7 s + r ) / 8 * * Since we don't actually store s, this reduces to * t := ( 7 t / 8 ) + ( r / 2 ) * */ if ( timer->count ) { timer->count--; } else { timer->timeout -= ( timer->timeout >> 3 ); timer->timeout += ( runtime >> 1 ); if ( timer->timeout != old_timeout ) { DBG ( "Timer %p timeout updated to %ld\n", timer, timer->timeout ); } } ref_put ( timer->refcnt ); }
static int numeric_resolv ( struct interface *resolv, const char *name, struct sockaddr *sa ) { struct numeric_resolv *numeric; /* Allocate and initialise structure */ numeric = zalloc ( sizeof ( *numeric ) ); if ( ! numeric ) return -ENOMEM; ref_init ( &numeric->refcnt, NULL ); intf_init ( &numeric->resolv, &null_intf_desc, &numeric->refcnt ); process_init ( &numeric->process, &numeric_process_desc, &numeric->refcnt ); memcpy ( &numeric->sa, sa, sizeof ( numeric->sa ) ); /* Attempt to resolve name */ numeric->rc = sock_aton ( name, &numeric->sa ); /* Attach to parent interface, mortalise self, and return */ intf_plug_plug ( &numeric->resolv, resolv ); ref_put ( &numeric->refcnt ); return 0; }
/** * Close Fibre Channel exchange * * @v xchg Fibre Channel exchange * @v rc Reason for close */ static void fc_xchg_close ( struct fc_exchange *xchg, int rc ) { struct fc_port *port = xchg->port; if ( rc != 0 ) { DBGC2 ( port, "FCXCHG %s/%04x closed: %s\n", port->name, xchg->xchg_id, strerror ( rc ) ); } /* Stop timer */ stop_timer ( &xchg->timer ); /* If list still holds a reference, remove from list of open * exchanges and drop list's reference. */ if ( ! list_empty ( &xchg->list ) ) { list_del ( &xchg->list ); INIT_LIST_HEAD ( &xchg->list ); ref_put ( &xchg->refcnt ); } /* Shutdown interfaces */ intf_shutdown ( &xchg->ulp, rc ); }
/******************************************************************************* * * Buffer functions. * ******************************************************************************/ int rb_create_buffer (struct rb_context* ctxt, const struct rb_buffer_desc* public_desc, const void* init_data, struct rb_buffer** out_buffer) { const struct rb_ogl3_buffer_desc private_desc = { .size = public_desc->size, .target = public_to_private_rb_target(public_desc->target), .usage = public_desc->usage }; return rb_ogl3_create_buffer(ctxt, &private_desc,init_data, out_buffer); } int rb_buffer_ref_get(struct rb_buffer* buffer) { if(!buffer) return -1; ref_get(&buffer->ref); return 0; } int rb_buffer_ref_put(struct rb_buffer* buffer) { if(!buffer) return -1; ref_put(&buffer->ref, release_buffer); return 0; } int rb_bind_buffer (struct rb_context* ctxt, struct rb_buffer* buffer, enum rb_buffer_target target) { return rb_ogl3_bind_buffer(ctxt, buffer, public_to_private_rb_target(target)); } int rb_buffer_data (struct rb_buffer* buffer, int offset, int size, const void* data) { void* mapped_mem = NULL; GLboolean unmap = GL_FALSE; if(!buffer || (offset < 0) || (size < 0) || (size != 0 && !data) || (buffer->size < offset + size)) return -1; if(size == 0) return 0; OGL(BindBuffer(buffer->target, buffer->name)); if(offset == 0 && size == buffer->size) { mapped_mem = OGL(MapBuffer(buffer->target, GL_WRITE_ONLY)); } else { const GLbitfield access = GL_MAP_WRITE_BIT; mapped_mem = OGL(MapBufferRange(buffer->target, offset, size, access)); } ASSERT(mapped_mem != NULL); memcpy(mapped_mem, data, (size_t)size); unmap = OGL(UnmapBuffer(buffer->target)); OGL(BindBuffer (buffer->target, buffer->ctxt->state_cache.buffer_binding[buffer->binding])); /* unmap == GL_FALSE must be handled by the application. TODO return a real * error code to differentiate this case from the error. */ return unmap == GL_TRUE ? 0 : -1; }
/** * Decrement reference count on an object interface * * @v intf Object interface */ void intf_put ( struct interface *intf ) { ref_put ( intf->refcnt ); }
/** * Resolve name using DNS * * @v resolv Name resolution interface * @v name Name to resolve * @v sa Socket address to fill in * @ret rc Return status code */ static int dns_resolv ( struct resolv_interface *resolv, const char *name, struct sockaddr *sa ) { struct dns_request *dns; char *fqdn; int rc; /* Fail immediately if no DNS servers */ if ( ! nameserver.st_family ) { DBG ( "DNS not attempting to resolve \"%s\": " "no DNS servers\n", name ); rc = -ENXIO; goto err_no_nameserver; } /* Ensure fully-qualified domain name if DHCP option was given */ fqdn = dns_qualify_name ( name ); if ( ! fqdn ) { rc = -ENOMEM; goto err_qualify_name; } /* Allocate DNS structure */ dns = zalloc ( sizeof ( *dns ) ); if ( ! dns ) { rc = -ENOMEM; goto err_alloc_dns; } resolv_init ( &dns->resolv, &null_resolv_ops, &dns->refcnt ); xfer_init ( &dns->socket, &dns_socket_operations, &dns->refcnt ); dns->timer.expired = dns_timer_expired; memcpy ( &dns->sa, sa, sizeof ( dns->sa ) ); /* Create query */ dns->query.dns.flags = htons ( DNS_FLAG_QUERY | DNS_FLAG_OPCODE_QUERY | DNS_FLAG_RD ); dns->query.dns.qdcount = htons ( 1 ); dns->qinfo = ( void * ) dns_make_name ( fqdn, dns->query.payload ); dns->qinfo->qtype = htons ( DNS_TYPE_A ); dns->qinfo->qclass = htons ( DNS_CLASS_IN ); /* Open UDP connection */ if ( ( rc = xfer_open_socket ( &dns->socket, SOCK_DGRAM, ( struct sockaddr * ) &nameserver, NULL ) ) != 0 ) { DBGC ( dns, "DNS %p could not open socket: %s\n", dns, strerror ( rc ) ); goto err_open_socket; } /* Send first DNS packet */ dns_send_packet ( dns ); /* Attach parent interface, mortalise self, and return */ resolv_plug_plug ( &dns->resolv, resolv ); ref_put ( &dns->refcnt ); free ( fqdn ); return 0; err_open_socket: err_alloc_dns: ref_put ( &dns->refcnt ); err_qualify_name: free ( fqdn ); err_no_nameserver: return rc; }
void bytes_put(struct bytes *bytes) { ref_put(&bytes->ref, bytes_free); }