static int vrt_publish_multi_threaded(struct vrt_queue *q, struct vrt_producer *p, vrt_value_id last_published_id) { bool first = true; vrt_value_id expected_cursor; vrt_value_id current_cursor; /* If there are multiple publisherthen we have to wait until all * of the values before the chunk that we claimed have been * published. (If we don't, there will be a hole in the sequence of * published records.) */ expected_cursor = last_published_id - p->batch_size; current_cursor = vrt_queue_get_cursor(q); clog_debug("<%s> Wait for value %d to be published", p->name, expected_cursor); while (vrt_mod_lt(current_cursor, expected_cursor)) { clog_trace("<%s> Last published value is %d (wait)", p->name, current_cursor); rii_check(vrt_yield_strategy_yield (p->yield, first, q->name, p->name)); first = false; current_cursor = vrt_queue_get_cursor(q); } clog_debug("<%s> Last published value is %d", p->name, current_cursor); clog_debug("<%s> Signal publication of value %d (multi-threaded)", p->name, last_published_id); vrt_queue_set_cursor(q, last_published_id); return 0; }
int maltcp_ctx_poller_wait( void *self, mal_poller_t *mal_poller, mal_endpoint_t **mal_endpoint, int timeout) { maltcp_poller_data_t *poller_data = (maltcp_poller_data_t *) mal_poller_get_poller_data(mal_poller); int rc = 0; clog_debug(maltcp_logger, "maltcp_ctx_poller_wait(%d)\n", timeout); zsock_t *which = (zsock_t *) zpoller_wait(poller_data->poller, timeout); if (zpoller_terminated(poller_data->poller)) { clog_debug(maltcp_logger, "maltcp_ctx_poller_wait: zpoller_terminated.\n"); return -1; } if (which) { maltcp_endpoint_data_t *endpoint_data = maltcp_get_endpoint(poller_data, which); if (endpoint_data != NULL) { *mal_endpoint = endpoint_data->mal_endpoint; clog_debug(maltcp_logger, "maltcp_ctx_poller_wait: data available for end-point %s\n", mal_endpoint_get_uri(*mal_endpoint)); } else { clog_error(maltcp_logger, "maltcp_ctx_poller_wait: cannot find corresponding end-point\n"); return -1; } } else { *mal_endpoint = NULL; } return rc; }
int maltcp_ctx_server_socket_create(int port, int backlog) { clog_debug(maltcp_logger, "maltcp_ctx: creates TCP server socket.\n"); int listen_socket = socket(AF_INET, SOCK_STREAM, 0); if (listen_socket == -1) { clog_error(maltcp_logger, "Failed to create listen socket: %s", strerror(errno)); return -1; } int one = 1; setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); // setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &one, sizeof(one)); // setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); struct sockaddr_in server_addr; bzero((char *) &server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(port); if (bind(listen_socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) == -1) { clog_error(maltcp_logger, "Failed to bind server to port %d: %s\n", port, strerror(errno)); return -1; } if (listen(listen_socket, backlog) == -1) { clog_error(maltcp_logger, "Failed to listen: %s", strerror(errno)); return -1; } clog_debug(maltcp_logger, "maltcp_ctx: TCP server socket created.\n"); return listen_socket; }
int maltcp_ctx_poller_del_endpoint( void *self, mal_poller_t *mal_poller, mal_endpoint_t *mal_endpoint) { maltcp_poller_data_t *poller_data = (maltcp_poller_data_t *) mal_poller_get_poller_data(mal_poller); maltcp_endpoint_data_t *endpoint_data = (maltcp_endpoint_data_t *) mal_endpoint_get_endpoint_data(mal_endpoint); int rc = 0; clog_debug(maltcp_logger, "maltcp_ctx_poller_del_endpoint(): %s\n", mal_endpoint_get_uri(mal_endpoint)); if (poller_data->poller == NULL) { clog_error(maltcp_logger, ""); return -1; } rc = zpoller_remove(poller_data->poller, endpoint_data->socket); if (rc != 0) { clog_error(maltcp_logger, "maltcp_ctx_poller_del_endpoint(): zpoller null\n"); return rc; } rc = maltcp_del_endpoint(poller_data, mal_endpoint); clog_debug(maltcp_logger, "maltcp_ctx_poller_del_endpoint: return %d\n",rc); return rc; }
/* Waits for the slot given by the producer's last_claimed_id to become * free. (This happens when every consumer has finished processing the * previous value that would've used the same slot in the ring buffer. */ static int vrt_wait_for_slot(struct vrt_queue *q, struct vrt_producer *p) { bool first = true; vrt_value_id wrapped_id = p->last_claimed_id - vrt_queue_size(q); if (vrt_mod_lt(q->last_consumed_id, wrapped_id)) { clog_debug("<%s> Wait for value %d to be consumed", p->name, wrapped_id); vrt_value_id minimum = vrt_queue_find_last_consumed_id(q); while (vrt_mod_lt(minimum, wrapped_id)) { clog_trace("<%s> Last consumed value is %d (wait)", p->name, minimum); p->yield_count++; rii_check(vrt_yield_strategy_yield (p->yield, first, q->name, p->name)); first = false; minimum = vrt_queue_find_last_consumed_id(q); } p->batch_count++; q->last_consumed_id = minimum; clog_debug("<%s> Last consumed value is %d", p->name, minimum); } return 0; }
int maltcp_ctx_socket_send(maltcp_ctx_connection_t *cnx, malbinary_cursor_t *cursor) { // Lock TCP connection. pthread_mutex_lock(&cnx->lock); clog_debug(maltcp_logger, "maltcp_ctx_socket_send: send TCP message, size=%d\n", malbinary_cursor_get_length(cursor)); int rc = send(cnx->socket, cursor->body_ptr, malbinary_cursor_get_length(cursor), 0); if (rc < 0) clog_error(maltcp_logger, "maltcp_ctx_socket_send: error sending message.\n"); else clog_debug(maltcp_logger, "maltcp_ctx_socket_send: message sent.\n"); // Unock TCP connection. pthread_mutex_unlock(&cnx->lock); return rc; }
maltcp_ctx_connection_t *maltcp_ctx_socket_connect(maltcp_ctx_t *self, mal_uri_t *socket_uri) { maltcp_ctx_connection_t *cnx_ptr = (maltcp_ctx_connection_t *) zhash_lookup(self->cnx_table, socket_uri); if (cnx_ptr == NULL) { clog_debug(maltcp_logger, "maltcp_ctx_socket_connect: open a new PTP socket\n"); // Create a new connection struct hostent *server; int client_socket = socket(AF_INET, SOCK_STREAM, 0); if (client_socket == -1) { clog_error(maltcp_logger, "maltcp_ctx_socket_connect: failed to create client socket: %s\n", strerror(errno)); return NULL; } char *ipaddr = maltcp_get_host_from_uri(socket_uri); int port = maltcp_get_port_from_uri(socket_uri); clog_debug(maltcp_logger, "maltcp_ctx_socket_connect: %s %d\n", ipaddr, port); if ((server = gethostbyname(ipaddr)) == NULL) { clog_error(maltcp_logger, "maltcp_ctx_socket_connect: failed to to get address: %s\n", strerror(errno)); free(ipaddr); return NULL; } free(ipaddr); struct sockaddr_in server_addr; bzero((char *) &server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&server_addr.sin_addr.s_addr, server->h_length); server_addr.sin_port = htons(port); if (connect(client_socket, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) { clog_error(maltcp_logger, "maltcp_ctx_socket_connect: failed to connect: %s\n", strerror(errno)); return NULL; } clog_debug(maltcp_logger, "maltcp_ctx_socket_connect: connected to %s\n", socket_uri); clog_debug(maltcp_logger, "maltcp_ctx_socket_connect: update TCP connections table\n"); cnx_ptr = maltcp_ctx_connection_register_outgoing(self, client_socket, socket_uri); // Register a zloop poller for this connection. zmq_pollitem_t poller = { NULL, client_socket, ZMQ_POLLIN }; int rc = zloop_poller(self->zloop, &poller, maltcp_ctx_socket_receive, self); assert(rc == 0); } else { clog_debug(maltcp_logger, "maltcp_ctx_socket_connect: use existing connection (%d) for %s\n", cnx_ptr->socket, socket_uri); } return cnx_ptr; }
int vrt_consumer_next(struct vrt_consumer *c, struct vrt_value **value) { do { unsigned int producer_count; struct vrt_value *v; rii_check(vrt_consumer_next_raw(c->queue, c)); v = vrt_queue_get(c->queue, c->current_id); switch (v->special) { case VRT_VALUE_NONE: *value = v; return 0; case VRT_VALUE_EOF: producer_count = cork_array_size(&c->queue->producers); c->eof_count++; clog_debug("<%s> Detected EOF (%u of %u) at value %d", c->name, c->eof_count, producer_count, c->current_id); if (c->eof_count == producer_count) { /* We've run out of values that we know can been * processed. Notify the world how much we've * processed so far. */ clog_debug("<%s> Signal consumption of %d", c->name, c->current_id); vrt_consumer_set_cursor(c, c->current_id); return VRT_QUEUE_EOF; } else { /* There are other producers still producing values, * so we should repeat the loop to grab the next * value. */ break; } case VRT_VALUE_HOLE: /* Repeat the loop to grab the next value. */ break; case VRT_VALUE_FLUSH: /* Return the FLUSH control message. */ return VRT_QUEUE_FLUSH; default: cork_unreachable(); } } while (true); }
int maltcp_ctx_stop(void *self) { maltcp_ctx_t *mal_ctx = (maltcp_ctx_t *) self; clog_debug(maltcp_logger, "maltcp_ctx_stop...\n"); if (mal_ctx->mal_socket != -1) { // Note: this method is not symmetric with maltcp_ctx_start, may be we have to // create and bind the socket in maltcp_ctx_start rather than in maltcp_ctx_new. int socket = mal_ctx->mal_socket; mal_ctx->mal_socket = -1; close(socket); } clog_debug(maltcp_logger, "maltcp_ctx_stop: stopped.\n"); return 0; }
// This function is called when an incoming connection is detected on the // listening socket. It accepts the connection and registers the appropriate // poller to receive message. int maltcp_ctx_socket_accept(zloop_t *zloop, zmq_pollitem_t *poller, void *arg) { maltcp_ctx_t *self = (maltcp_ctx_t *) arg; clog_debug(maltcp_logger, "maltcp_ctx: TCP server socket accept.\n"); if (self->mal_socket == -1) { // The context is closed, return clog_debug(maltcp_logger, "maltcp_ctx_socket_accept: socket (%d) closed\n", poller->fd); return -1; } // Accept incoming connection and register it. struct sockaddr src_addr; int new_socket = -1; socklen_t len = sizeof(struct sockaddr_in); // Note: May be we could use poller->fd to replace self->mal_socket if ((new_socket = accept(self->mal_socket, &src_addr, &len)) == -1) { clog_error(maltcp_logger, "Failed to accept: %s\n", strerror(errno)); return -1; } if (clog_is_loggable(maltcp_logger, CLOG_DEBUG_LEVEL)) { // Needed only for debug. char src_ipstr[INET6_ADDRSTRLEN]; int src_port; if (src_addr.sa_family == AF_INET) { struct sockaddr_in *s = (struct sockaddr_in *)&src_addr; src_port = ntohs(s->sin_port); inet_ntop(AF_INET, &s->sin_addr, src_ipstr, sizeof src_ipstr); } else { // AF_INET6 struct sockaddr_in6 *s = (struct sockaddr_in6 *)&src_addr; src_port = ntohs(s->sin6_port); inet_ntop(AF_INET6, &s->sin6_addr, src_ipstr, sizeof src_ipstr); } clog_debug(maltcp_logger, "maltcp_ctx_socket_accept: Source URI: %s%s:%d\n", MALTCP_URI, src_ipstr, src_port); } zmq_pollitem_t poller2 = { NULL, new_socket, ZMQ_POLLIN }; int rc = zloop_poller(zloop, &poller2, maltcp_ctx_socket_receive, self); assert(rc == 0); // Note: do not register the connection since the uri is not yet precisely known. clog_debug(maltcp_logger, "maltcp_ctx: TCP connection established.\n"); return 0; }
int maltcp_del_endpoint(maltcp_poller_data_t *poller_data, mal_endpoint_t *endpoint) { clog_info(maltcp_logger, " *** maltcp_del_endpoint: %s\n", mal_endpoint_get_uri(endpoint)); int found = -1; for (int i=0; i<poller_data->idx; i++) { if ((poller_data->endpoints[i] != NULL) && (poller_data->endpoints[i] == mal_endpoint_get_endpoint_data(endpoint))) { found = i; break; } } if (found == -1) { clog_warning(maltcp_logger, " *** maltcp_del_endpoint: Not found\n"); return -1; } poller_data->idx -= 1; for (int i=found; i<poller_data->idx; i++) { poller_data->endpoints[i] = poller_data->endpoints[i+1]; } poller_data->endpoints[poller_data->idx] = NULL; clog_debug(maltcp_logger, " *** maltcp_del_endpoint: OK\n"); return 0; }
int main(int argc, char *argv[]) { int level = CLOG_DEFAULT; const char *lname = "DEFAULT"; clog_init(stdout, level, CLOG_DEFAULT_TS_FMT); if(argc == 2) { if(!strcmp("FATAL", argv[1])) { clog_set_level(level = CLOG_FATAL); lname = "FATAL"; } if(!strcmp("ERROR", argv[1])) { clog_set_level(level = CLOG_ERROR); lname = "ERROR"; } if(!strcmp("WARN", argv[1])) { clog_set_level(level = CLOG_WARN); lname = "WARN"; } if(!strcmp("INFO", argv[1])) { clog_set_level(level = CLOG_INFO); lname = "INFO"; } if(!strcmp("DEBUG", argv[1])) { clog_set_level(level = CLOG_DEBUG); lname = "DEBUG"; } if(!strcmp("TRACE", argv[1])) { clog_set_level(level = CLOG_TRACE); lname = "TRACE"; } } fprintf(stdout, "--- %s ---\n", lname); clog_fatal("this is %s log", "fatal"); clog_error("this is %s log", "error"); clog_warn("this is %s log", "warn"); clog_info("this is %s log", "info"); clog_debug("this is %s log", "debug"); clog_trace("this is %s log", "trace"); return 0; }
/** * Send a command to gdb. * * @param tgdb * An instance of tgdb * * @param request * The command request to issue the command for */ static void tgdb_run_request(struct tgdb *tgdb, struct tgdb_request *request) { std::string command; if (request->header == TGDB_REQUEST_CONSOLE_COMMAND || request->header == TGDB_REQUEST_COMPLETE || request->header == TGDB_REQUEST_DEBUGGER_COMMAND) { tgdb->make_console_ready_callback = true; } tgdb->is_gdb_ready_for_next_command = 0; tgdb_get_gdb_command(tgdb, request, command); /* Add a newline to the end of the command if it doesn't exist */ if (*command.rbegin() != '\n') { command.push_back('\n'); } /* Send what we're doing to log file */ char *str = sys_quote_nonprintables(command.c_str(), -1); clog_debug(CLOG_GDBIO, "%s", str); sbfree(str); /* A command for the debugger */ commands_set_current_request_type(tgdb->c, request->header); io_writen(tgdb->debugger_stdin, command.c_str(), command.size()); // Alert the GUI a command was sent tgdb->callbacks.request_sent_callback( tgdb->callbacks.context, request, command); tgdb_request_destroy(request); }
static int vrt_queue_add_producer(struct vrt_queue *q, struct vrt_producer *p) { clog_debug("[%s] Add producer %s", q->name, p->name); /* Add the producer to the queue's array and assign its index. */ cork_array_append(&q->producers, p); p->queue = q; p->index = cork_array_size(&q->producers) - 1; /* Choose the right claim and publish implementations for this * producer. */ if (p->index == 0) { /* If this is the first producer, use faster claim and publish * methods that are optimized for the single-producer case. */ p->claim = vrt_claim_single_threaded; p->publish = vrt_publish_single_threaded; } else { /* Otherwise we need to use slower, but multiple-producer- * capable, implementations of claim and publish. */ p->claim = vrt_claim_multi_threaded; p->publish = vrt_publish_multi_threaded; /* If this is the second producer, then we need to update the * first producer to also use the slower implementations. */ if (p->index == 1) { struct vrt_producer *first = cork_array_at(&q->producers, 0); first->claim = vrt_claim_multi_threaded; first->publish = vrt_publish_multi_threaded; } } return 0; }
void *maltcp_ctx_create_poller(void *maltcp_ctx, mal_poller_t *mal_poller) { maltcp_ctx_t *self = (maltcp_ctx_t *) maltcp_ctx; clog_debug(maltcp_logger, "maltcp_ctx_create_poller()\n"); maltcp_poller_data_t *poller_data = (maltcp_poller_data_t *) zmalloc(sizeof(maltcp_poller_data_t)); assert(poller_data); // Initialize the poller ZMQ specific state poller_data->maltcp_ctx = self; poller_data->mal_poller = mal_poller; poller_data->max = MAL_POLLER_LIST_DFLT_SIZE; poller_data->idx = 0; poller_data->endpoints = (maltcp_endpoint_data_t **) calloc(MAL_POLLER_LIST_DFLT_SIZE, sizeof(maltcp_endpoint_data_t *)); if (poller_data->endpoints == NULL) { free(self); return NULL; } poller_data->poller = NULL; mal_poller_set_poller_data(mal_poller, poller_data); return poller_data; }
ssize_t io_read(int fd, void *buf, size_t count) { ssize_t amountRead; tgdb_read: if ((amountRead = read(fd, buf, count)) == -1) { /* error */ if (errno == EINTR) goto tgdb_read; else if (errno != EIO) { logger_write_pos(logger, __FILE__, __LINE__, "error reading from fd"); return -1; } else { return 0; /* Happens on EOF for some reason */ } } else if (amountRead == 0) { /* EOF */ return 0; } else { char *str = sys_quote_nonprintables((char *)buf, amountRead); clog_debug(CLOG(TGDB_LOGGER), "%s", str); sbfree(str); } return amountRead; }
int maltcp_ctx_connection_remove_socket(maltcp_ctx_t *self, int socket) { clog_debug(maltcp_logger, "maltcp_ctx_connection_remove_socket(%d).\n", socket); maltcp_ctx_connection_t *cnx_ptr = (maltcp_ctx_connection_t*) zhash_first(self->cnx_table); while (cnx_ptr) { if (cnx_ptr->socket == socket) { // Close registered TCP connections clog_debug(maltcp_logger, "maltcp_ctx_connection_remove_socket: close and remove socket.\n"); maltcp_ctx_socket_destroy(cnx_ptr); zhash_delete(self->cnx_table, zhash_cursor(self->cnx_table)); // TODO: Should free the allocated string key and element structure. return 0; } cnx_ptr = (maltcp_ctx_connection_t*) zhash_next(self->cnx_table); } clog_debug(maltcp_logger, "maltcp_ctx_connection_remove_socket: socket (%d) not found.\n", socket); return 0; }
void *maltcp_ctx_create_endpoint(void *maltcp_ctx, mal_endpoint_t *mal_endpoint) { maltcp_ctx_t *self = (maltcp_ctx_t *) maltcp_ctx; maltcp_endpoint_data_t *endpoint_data = NULL; clog_debug(maltcp_logger, "maltcp_ctx_create_endpoint()\n"); if (mal_endpoint) { endpoint_data = (maltcp_endpoint_data_t *) zmalloc(sizeof(maltcp_endpoint_data_t)); assert(endpoint_data); // Initialize the endpoint ZMQ specific state endpoint_data->maltcp_ctx = self; endpoint_data->mal_endpoint = mal_endpoint; mal_endpoint_set_endpoint_data(mal_endpoint, endpoint_data); clog_debug(maltcp_logger, "maltcp_ctx_create_endpoint: initialize endpoint\n"); // Initialize the endpoint mal_uri_t *handler_uri = maltcp_get_service_from_uri(mal_endpoint_get_uri(endpoint_data->mal_endpoint)); clog_debug(maltcp_logger, "maltcp_ctx_create_endpoint: initialize endpoint -> %s\n", handler_uri); // Create a socket connected to the zloop to receive // MAL messages to be handled by this actor void *zloop_socket = zsocket_new(self->zmq_ctx, ZMQ_DEALER); // Keep the socket endpoint_data->socket = zloop_socket; // The identity of the handler is its URI zmq_setsockopt(zloop_socket, ZMQ_IDENTITY, handler_uri, strlen(handler_uri)); // Connect to the zloop clog_debug(maltcp_logger, "maltcp_ctx_create_endpoint: connect to the zloop\n"); zmq_connect(zloop_socket, ZLOOP_ENDPOINTS_SOCKET_URI); clog_debug(maltcp_logger, "maltcp_ctx_create_endpoint: initialized.\n"); } else { clog_error(maltcp_logger, "maltcp_ctx_create_endpoint, cannot create end-point: %s\n", mal_endpoint_get_uri(endpoint_data->mal_endpoint)); } return endpoint_data; }
int malzmq_encode_time(mal_encoder_t *encoder, void *cursor, mal_time_t to_encode) { int rc = 0; clog_debug(malzmq_logger, "malzmq_encode_time: to_encode = %lu\n", to_encode); long timestamp = to_encode; timestamp += MILLISECONDS_FROM_CCSDS_TO_UNIX_EPOCH; long days = timestamp / MILLISECONDS_IN_DAY; long millisecondsInDay = (timestamp % MILLISECONDS_IN_DAY); if (days > 65535) { clog_debug(malzmq_logger, "malzmq_encode_time: days > 65535\n"); return 1; } malbinary_write16(days, cursor); malbinary_write32(millisecondsInDay, cursor); return rc; }
int maltcp_ctx_destroy(void **self_p) { clog_debug(maltcp_logger, "maltcp_ctx_destroy...\n"); if (self_p && *self_p) { maltcp_ctx_t *self = (maltcp_ctx_t *) *self_p; // TODO(AF): zmq_close versus zsocket_destroy zsocket_set_linger(self->endpoints_socket, 0); clog_debug(maltcp_logger, "maltcp_ctx_destroy: linger=%d\n", zsocket_linger(self->endpoints_socket)); zsocket_destroy(self->zmq_ctx, self->endpoints_socket); // zmq_close(mal_ctx->endpoints_socket); // Free all structures in hash-table, close socket and destroy mutex. if (self->cnx_table) { maltcp_ctx_connection_t *cnx_ptr = (maltcp_ctx_connection_t*) zhash_first(self->cnx_table); while (cnx_ptr) { // Close registered TCP connections clog_debug(maltcp_logger, "maltcp_ctx_destroy: close socket %d.\n", cnx_ptr->socket); maltcp_ctx_socket_destroy(cnx_ptr); // destroy all registered sockets cnx_ptr = (maltcp_ctx_connection_t*) zhash_next(self->cnx_table); } } // TODO (AF): Close all pollers? clog_debug(maltcp_logger, "maltcp_ctx_destroy: stopped.\n"); free(self->maltcp_header); // Free all structures in hash-table, close socket and destroy mutex. if (self->cnx_table) zhash_destroy(&self->cnx_table); zloop_destroy(&self->zloop); // zsocket_destroy(self->zmq_ctx, self->endpoints_socket); // zmq_close(self->endpoints_socket); zctx_destroy(&self->zmq_ctx); free(self); *self_p = NULL; } clog_debug(maltcp_logger, "maltcp_ctx_destroy: destroyed.\n"); return 0; }
static int vrt_queue_add_consumer(struct vrt_queue *q, struct vrt_consumer *c) { clog_debug("[%s] Add consumer %s", q->name, c->name); /* Add the consumer to the queue's array and assign its index. */ cork_array_append(&q->consumers, c); c->queue = q; c->index = cork_array_size(&q->consumers) - 1; return 0; }
maltcp_endpoint_data_t* maltcp_get_endpoint(maltcp_poller_data_t *poller_data, zsock_t *socket) { clog_info(maltcp_logger, " *** mal_routing_get_endpoint: \n"); for (int i=0; i<poller_data->idx; i++) { if (poller_data->endpoints[i]->socket == socket) { clog_debug(maltcp_logger, " *** mal_routing_get_endpoint: OK\n"); return poller_data->endpoints[i]; } } return NULL; }
void maltcp_ctx_destroy_endpoint(void *self, void **endpoint_p) { assert(endpoint_p); if (*endpoint_p) { maltcp_endpoint_data_t *endpoint = *(maltcp_endpoint_data_t **) endpoint_p; *endpoint_p = NULL; clog_debug(maltcp_logger, "maltcp_ctx_destroy_endpoint(): %d ..\n", endpoint->socket); // NOTE: Closing this socket makes a core dump during maltcp_ctx_destroy !! zsock_set_linger(endpoint->socket, 0); // zsocket_destroy(endpoint->maltcp_ctx->zmq_ctx, endpoint->socket); // zmq_close(endpoint->socket); // ... destroy your own state here // mal_ctx and mal_endpoint must not be destroyed here // but where they have been created. free(endpoint); clog_debug(maltcp_logger, "maltcp_ctx_destroy_endpoint().\n"); } }
int vrt_producer_eof(struct vrt_producer *p) { struct vrt_value *v; rii_check(vrt_producer_claim_raw(p->queue, p)); clog_debug("<%s> EOF %d", p->name, p->last_produced_id); v = vrt_queue_get(p->queue, p->last_produced_id); v->id = p->last_produced_id; v->special = VRT_VALUE_EOF; rii_check(vrt_producer_publish(p)); return vrt_producer_flush(p); }
// Must be compliant with MAL virtual function: void *self mal_uri_t *maltcp_ctx_create_uri(void *self, char *id) { maltcp_ctx_t *maltcp_ctx = (maltcp_ctx_t *) self; clog_debug(maltcp_logger, "maltcp_ctx_create_uri()\n"); size_t uri_length = strlen(MALTCP_URI); if (maltcp_ctx->hostname) { uri_length += strlen(maltcp_ctx->hostname); } if (maltcp_ctx->port) { uri_length += strlen(maltcp_ctx->port) + 1; } if (id) { uri_length += strlen(id) + 1; } clog_debug(maltcp_logger, "maltcp_ctx: uri_length=%d\n", uri_length); char *uri = (char *) malloc(uri_length + 1); // Need to set the final '\0' before using strcat uri[0] = '\0'; if (uri) { strcat(uri, MALTCP_URI); if (maltcp_ctx->hostname) { strcat(uri, maltcp_ctx->hostname); } if (maltcp_ctx->port) { strcat(uri, ":"); strcat(uri, maltcp_ctx->port); } if (id) { strcat(uri, "/"); strcat(uri, id); } } clog_debug(maltcp_logger, "maltcp_ctx: created URI: %s\n", uri); return uri; }
static int vrt_publish_single_threaded(struct vrt_queue *q, struct vrt_producer *p, vrt_value_id last_published_id) { /* If there's only a single producer, we can just update the queue's * cursor. We don't have to wait for anything, because the claim * function will have already ensured that this slot was free to * fill in and publish. */ clog_debug("<%s> Signal publication of value %d (single-threaded)", p->name, last_published_id); vrt_queue_set_cursor(q, last_published_id); return 0; }
// Returns a newly allocated string containing the IP address from the URI specified // in parameter: "maltcp://ipaddress:port/service" -> "ipaddress" char *malzmq_get_host_from_uri(char *uri) { // TODO (AF): IPv6 char* ptr1 = strchr(uri +sizeof MALZMTP_URI -1, ':'); if (ptr1 == NULL) return NULL; size_t len = (size_t) (ptr1 - uri -sizeof MALZMTP_URI +1); char* host = (char*) malloc(len +1); strncpy(host, uri +sizeof MALZMTP_URI -1, len); host[len] = '\0'; clog_debug(malzmq_logger, "get_host_from_uri(%s) /%d -> %s\n", uri, len, host); return host; }
int maltcp_ctx_poller_add_endpoint( void *self, mal_poller_t *mal_poller, mal_endpoint_t *mal_endpoint) { maltcp_poller_data_t *poller_data = (maltcp_poller_data_t *) mal_poller_get_poller_data(mal_poller); maltcp_endpoint_data_t *endpoint_data = (maltcp_endpoint_data_t *) mal_endpoint_get_endpoint_data(mal_endpoint); int rc = 0; clog_debug(maltcp_logger, "maltcp_ctx_poller_add_endpoint(): %s\n", mal_endpoint_get_uri(mal_endpoint)); maltcp_add_endpoint(poller_data, mal_endpoint); if (poller_data->poller == NULL) poller_data->poller = zpoller_new(endpoint_data->socket, NULL); else rc = zpoller_add(poller_data->poller, endpoint_data->socket); return rc; }
struct vrt_queue * vrt_queue_new(const char *name, struct vrt_value_type *value_type, unsigned int size) { struct vrt_queue *q = cork_new(struct vrt_queue); memset(q, 0, sizeof(struct vrt_queue)); q->name = cork_strdup(name); unsigned int value_count; if (size == 0) { value_count = DEFAULT_QUEUE_SIZE; } else { if (size < MINIMUM_QUEUE_SIZE) { size = MINIMUM_QUEUE_SIZE; } value_count = min_power_of_2(size); } q->value_mask = value_count - 1; q->last_consumed_id = starting_value; q->last_claimed_id.value = q->last_consumed_id; q->cursor.value = q->last_consumed_id; q->value_type = value_type; q->values = cork_calloc(value_count, sizeof(struct vrt_value *)); clog_debug("[%s] Create queue with %u entries", q->name, value_count); cork_pointer_array_init(&q->producers, (cork_free_f) vrt_producer_free); cork_pointer_array_init(&q->consumers, (cork_free_f) vrt_consumer_free); unsigned int i; for (i = 0; i < value_count; i++) { q->values[i] = vrt_value_new(value_type); cork_abort_if_null(q->values[i], "Cannot allocate values"); } return q; }
int malzmq_encode_message(malzmq_header_t *malzmq_header, mal_message_t *message, mal_encoder_t *encoder, void *cursor) { clog_debug(mal_encoder_get_logger(encoder), "malzmq_encode_message()\n"); int sdu_type = convert_to_sdu_type( mal_message_get_interaction_type(message), mal_message_get_interaction_stage(message), mal_message_is_error_message(message)); if (sdu_type == -1) { clog_error(malzmq_logger, MALZMQ_BAD_SDU_TYPE_MSG); return MALZMQ_BAD_SDU_TYPE; } ((malbinary_cursor_t *) cursor)->body_ptr[((malbinary_cursor_t *) cursor)->body_offset++] = (char) ((malzmq_header_get_version(malzmq_header) << 5) | sdu_type); malbinary_write16(mal_message_get_service_area(message), cursor); malbinary_write16(mal_message_get_service(message), cursor); malbinary_write16(mal_message_get_operation(message), cursor); ((malbinary_cursor_t *) cursor)->body_ptr[((malbinary_cursor_t *) cursor)->body_offset++] = mal_message_get_area_version(message); ((malbinary_cursor_t *) cursor)->body_ptr[((malbinary_cursor_t *) cursor)->body_offset++] = (char) ((mal_message_is_error_message(message) << 7) | (mal_message_get_qoslevel(message) << 4) | (mal_message_get_session(message))); malbinary_write64(mal_message_get_transaction_id(message), cursor); char encoding_id_flag; mal_uoctet_t encoding_id = mal_message_get_encoding_id(message); if (encoding_id < 3) encoding_id_flag = encoding_id; else encoding_id_flag = 3; bool priority_flag = malzmq_header_get_priority_flag(malzmq_header); bool timestamp_flag = malzmq_header_get_timestamp_flag(malzmq_header); bool network_zone_flag = malzmq_header_get_network_zone_flag(malzmq_header); bool session_name_flag = malzmq_header_get_session_name_flag(malzmq_header); bool domain_flag = malzmq_header_get_domain_flag(malzmq_header); bool authentication_id_flag = malzmq_header_get_authentication_id_flag(malzmq_header); ((malbinary_cursor_t *) cursor)->body_ptr[((malbinary_cursor_t *) cursor)->body_offset++] = (char) (encoding_id_flag << 6) | (priority_flag << 5) | (timestamp_flag << 4) | (network_zone_flag << 3) | (session_name_flag << 2) | (domain_flag << 1) | (authentication_id_flag << 0); // always encode 'URI From' and 'URI To' malzmq_encode_uri(mal_message_get_uri_from(message), malzmq_header_get_mapping_directory(malzmq_header), encoder, cursor); malzmq_encode_uri(mal_message_get_uri_to(message), malzmq_header_get_mapping_directory(malzmq_header), encoder, cursor); if (encoding_id_flag == 3) { malbinary_encoder_encode_uoctet(encoder, cursor, encoding_id); } if (priority_flag > 0) { malbinary_encoder_encode_uinteger(encoder, cursor, mal_message_get_priority(message)); } if (timestamp_flag != false) { malzmq_encode_time(encoder, cursor, mal_message_get_timestamp(message)); } if (network_zone_flag > 0) { malzmq_encode_identifier(mal_message_get_network_zone(message), malzmq_header_get_mapping_directory(malzmq_header), encoder, cursor); } if (session_name_flag > 0) { malzmq_encode_identifier(mal_message_get_session_name(message), malzmq_header_get_mapping_directory(malzmq_header), encoder, cursor); } if (domain_flag > 0) { malzmq_encode_identifier_list(mal_message_get_domain(message), malzmq_header_get_mapping_directory(malzmq_header), encoder, cursor); } if (authentication_id_flag > 0) { malbinary_encoder_encode_blob(encoder, cursor, mal_message_get_authentication_id(message)); } // Copy the body in the frame. unsigned int body_length = mal_message_get_body_length(message); if (body_length > 0) { char *body = mal_message_get_body(message); unsigned int body_offset = mal_message_get_body_offset(message); char *bytes = ((malbinary_cursor_t *) cursor)->body_ptr; unsigned int index = ((malbinary_cursor_t *) cursor)->body_offset; memcpy(bytes + index, body + body_offset, body_length); ((malbinary_cursor_t *) cursor)->body_offset += body_length; } return 0; }