/* Internal Function: Workhorse function to send response back to the client * after UDF execution. * * caller: * send_success * send_failure * * Assumption: The call should be setup properly pointing to the tr. * * Special Handling: If it is background scan udf job do not sent any * response to client * If it is scan job ...do not cleanup the fd it will * be done by the scan thread after scan is finished */ static int send_response(udf_call *call, const char *key, size_t klen, int vtype, void *val, size_t vlen) { as_transaction * tr = call->transaction; as_namespace * ns = tr->rsv.ns; uint32_t generation = tr->generation; uint sp_sz = 1024 * 16; uint32_t void_time = 0; uint written_sz = 0; bool keep_fd = false; as_bin stack_bin; as_bin * bin = &stack_bin; // space for the stack particles uint8_t stack_particle_buf[sp_sz]; uint8_t * sp_p = stack_particle_buf; if (call->udf_type == AS_SCAN_UDF_OP_BACKGROUND) { // If we are doing a background UDF scan, do not send any result back cf_detail(AS_UDF, "UDF: Background transaction, send no result back. " "Parent job id [%"PRIu64"]", ((tscan_job*)(tr->udata.req_udata))->tid); if(strncmp(key, "FAILURE", 8) == 0) { cf_atomic_int_incr(&((tscan_job*)(tr->udata.req_udata))->n_obj_udf_failed); } else if(strncmp(key, "SUCCESS", 8) == 0) { cf_atomic_int_incr(&((tscan_job*)(tr->udata.req_udata))->n_obj_udf_success); } return 0; } else if(call->udf_type == AS_SCAN_UDF_OP_UDF) { // Do not release fd now, scan will do it at the end of all internal // udf transactions cf_detail(AS_UDF, "UDF: Internal udf transaction, do not release fd"); keep_fd = true; } if (0 != make_send_bin(ns, bin, &sp_p, sp_sz, key, klen, vtype, val, vlen)) { return(-1); } // this is going to release the file descriptor if (keep_fd && tr->proto_fd_h) cf_rc_reserve(tr->proto_fd_h); single_transaction_response( tr, ns, NULL/*ops*/, &bin, 1, generation, void_time, &written_sz, NULL); // clean up. // TODO: check: is bin_inuse valid only when data_in_memory? // There must be another way to determine if the particle is used? if ( as_bin_inuse(bin) ) { as_particle_destroy(&stack_bin, ns->storage_data_in_memory); } if (sp_p != stack_particle_buf) { cf_free(sp_p); } return 0; } // end send_response()
void as_bin_destroy_from(as_storage_rd *rd, uint16_t from) { for (uint16_t i = from; i < rd->n_bins; i++) { if (! as_bin_inuse(&rd->bins[i])) { break; } as_particle_destroy(&rd->bins[i], rd->ns->storage_data_in_memory); } as_bin_set_empty_from(rd, from); }
void as_bin_destroy(as_storage_rd *rd, uint16_t i) { as_particle_destroy(&rd->bins[i], rd->ns->storage_data_in_memory); as_bin_set_empty_shift(rd, i); }