static gboolean claim_op (GTlsConnectionBase *tls, GTlsConnectionBaseOp op, gboolean blocking, GCancellable *cancellable, GError **error) { try_again: if (g_cancellable_set_error_if_cancelled (cancellable, error)) return FALSE; g_mutex_lock (&tls->op_mutex); if (((op == G_TLS_CONNECTION_BASE_OP_HANDSHAKE || op == G_TLS_CONNECTION_BASE_OP_READ) && (tls->read_closing || tls->read_closed)) || ((op == G_TLS_CONNECTION_BASE_OP_HANDSHAKE || op == G_TLS_CONNECTION_BASE_OP_WRITE) && (tls->write_closing || tls->write_closed))) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, _("Connection is closed")); g_mutex_unlock (&tls->op_mutex); return FALSE; } if (tls->handshake_error && op != G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH && op != G_TLS_CONNECTION_BASE_OP_CLOSE_READ && op != G_TLS_CONNECTION_BASE_OP_CLOSE_WRITE) { if (error) *error = g_error_copy (tls->handshake_error); g_mutex_unlock (&tls->op_mutex); return FALSE; } if (op != G_TLS_CONNECTION_BASE_OP_HANDSHAKE) { if (op != G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH && op != G_TLS_CONNECTION_BASE_OP_CLOSE_READ && op != G_TLS_CONNECTION_BASE_OP_CLOSE_WRITE && tls->need_handshake && !tls->handshaking) { tls->handshaking = TRUE; if (!do_implicit_handshake (tls, blocking, cancellable, error)) { g_cancellable_reset (tls->waiting_for_op); g_mutex_unlock (&tls->op_mutex); return FALSE; } } if (tls->need_finish_handshake && tls->implicit_handshake) { GError *my_error = NULL; gboolean success; tls->need_finish_handshake = FALSE; g_mutex_unlock (&tls->op_mutex); success = finish_handshake (tls, tls->implicit_handshake, &my_error); g_clear_object (&tls->implicit_handshake); g_mutex_lock (&tls->op_mutex); if (op != G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH && op != G_TLS_CONNECTION_BASE_OP_CLOSE_READ && op != G_TLS_CONNECTION_BASE_OP_CLOSE_WRITE && (!success || g_cancellable_set_error_if_cancelled (cancellable, &my_error))) { g_propagate_error (error, my_error); g_mutex_unlock (&tls->op_mutex); return FALSE; } g_clear_error (&my_error); } } if ((op != G_TLS_CONNECTION_BASE_OP_WRITE && tls->reading) || (op != G_TLS_CONNECTION_BASE_OP_READ && tls->writing) || (op != G_TLS_CONNECTION_BASE_OP_HANDSHAKE && tls->handshaking)) { GPollFD fds[2]; int nfds; g_cancellable_reset (tls->waiting_for_op); g_mutex_unlock (&tls->op_mutex); if (!blocking) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, _("Operation would block")); return FALSE; } g_cancellable_make_pollfd (tls->waiting_for_op, &fds[0]); if (g_cancellable_make_pollfd (cancellable, &fds[1])) nfds = 2; else nfds = 1; g_poll (fds, nfds, -1); if (nfds > 1) g_cancellable_release_fd (cancellable); goto try_again; } if (op == G_TLS_CONNECTION_BASE_OP_HANDSHAKE) tls->handshaking = TRUE; if (op == G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH || op == G_TLS_CONNECTION_BASE_OP_CLOSE_READ) tls->read_closing = TRUE; if (op == G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH || op == G_TLS_CONNECTION_BASE_OP_CLOSE_WRITE) tls->write_closing = TRUE; if (op != G_TLS_CONNECTION_BASE_OP_WRITE) tls->reading = TRUE; if (op != G_TLS_CONNECTION_BASE_OP_READ) tls->writing = TRUE; g_mutex_unlock (&tls->op_mutex); return TRUE; }
/** * EscalateSubprocessShutdown: * @self: Subprocess that won't have any more messages sent to it. * @timeout_ms: Maximum time in milliseconds to wait for its stdout to close * before sending SIGKILL to the process. * @error: (out)(allow-none): Error return location or #NULL. * * Returns: #TRUE if stdout closed and had no more messages, or #FALSE if @error * is set and SIGKILL was sent. */ gboolean EscalateSubprocessShutdown(EscalateSubprocess *self, guint timeout_ms, GError **error) { GIOChannel *child_stdout = self->child_stdout; g_assert(child_stdout); GIOStatus status = G_IO_STATUS_ERROR; gint64 start_time = g_get_monotonic_time(); GPollFD poll_fd = { g_io_channel_unix_get_fd(child_stdout), G_IO_IN | G_IO_HUP | G_IO_ERR, 0 }; gchar leftover = '\0'; gsize leftover_length = 0; gboolean result = FALSE; g_assert(self->child_pid); if (self->child_stdin) g_io_channel_unref(self->child_stdin); self->child_stdin = NULL; self->child_stdout = NULL; do { status = g_io_channel_set_flags(child_stdout, G_IO_FLAG_NONBLOCK, NULL); } while (status == G_IO_STATUS_AGAIN); g_assert(status == G_IO_STATUS_NORMAL); do { // Wait for stdout to be readable. gint poll_timeout = timeout_ms - (g_get_monotonic_time() - start_time)/1000; gint poll_result = 0; if (poll_timeout > 0) poll_result = g_poll(&poll_fd, 1, poll_timeout); if (poll_result == 0) { g_set_error(error, ESCALATE_SUBPROCESS_ERROR, ESCALATE_SUBPROCESS_ERROR_SHUTDOWN_TIMEOUT, "Timed out waiting for subprocess to exit"); goto done; } // Try to read one more character so we know if there are any messages // waiting to be read. status = g_io_channel_read_chars(child_stdout, &leftover, 1, &leftover_length, error); } while (status == G_IO_STATUS_AGAIN); switch (status) { case G_IO_STATUS_NORMAL: g_assert(leftover_length == 1); g_set_error(error, ESCALATE_SUBPROCESS_ERROR, ESCALATE_SUBPROCESS_ERROR_LEFTOVER_STDOUT, "Subprocess stdout had unread messages"); break; case G_IO_STATUS_EOF: result = TRUE; break; default: g_assert(!error || *error); } done: if (!result && self->child_pid > 0) { g_assert(kill(self->child_pid, SIGKILL) == 0); self->child_pid = 0; } g_io_channel_unref(child_stdout); return result; }
static void * arv_gv_stream_thread (void *data) { ArvGvStreamThreadData *thread_data = data; ArvGvStreamFrameData *frame; ArvGvspPacket *packet; guint32 packet_id; guint32 frame_id; GTimeVal current_time; guint64 time_us; GPollFD poll_fd; size_t read_count; int timeout_ms; int n_events; int i; gboolean first_packet = TRUE; thread_data->frames = NULL; arv_debug_stream_thread ("[GvStream::stream_thread] Packet timeout = %g ms", thread_data->packet_timeout_us / 1000.0); arv_debug_stream_thread ("[GvStream::stream_thread] Frame retention = %g ms", thread_data->frame_retention_us / 1000.0); if (thread_data->callback != NULL) thread_data->callback (thread_data->user_data, ARV_STREAM_CALLBACK_TYPE_INIT, NULL); poll_fd.fd = g_socket_get_fd (thread_data->socket); poll_fd.events = G_IO_IN; poll_fd.revents = 0; packet = g_malloc0 (ARV_GV_STREAM_INCOMING_BUFFER_SIZE); do { if (thread_data->frames != NULL) timeout_ms = thread_data->packet_timeout_us / 1000; else timeout_ms = ARV_GV_STREAM_POLL_TIMEOUT_US / 1000; n_events = g_poll (&poll_fd, 1, timeout_ms); g_get_current_time (¤t_time); time_us = current_time.tv_sec * 1000000 + current_time.tv_usec; if (n_events > 0) { thread_data->n_received_packets++; read_count = g_socket_receive (thread_data->socket, (char *) packet, ARV_GV_STREAM_INCOMING_BUFFER_SIZE, NULL, NULL); frame_id = arv_gvsp_packet_get_frame_id (packet); packet_id = arv_gvsp_packet_get_packet_id (packet); if (first_packet) { thread_data->last_frame_id = frame_id - 1; first_packet = FALSE; } frame = _find_frame_data (thread_data, frame_id, packet, packet_id, read_count, time_us); if (frame != NULL) { ArvGvspPacketType packet_type = arv_gvsp_packet_get_packet_type (packet); if (packet_type != ARV_GVSP_PACKET_TYPE_OK && packet_type != ARV_GVSP_PACKET_TYPE_RESEND) { arv_debug_stream_thread ("[GvStream::stream_thread]" " Error packet at dt = %" G_GINT64_FORMAT ", packet id = %u" " frame id = %u", time_us - frame->first_packet_time_us, packet_id, frame->frame_id); arv_gvsp_packet_debug (packet, read_count, ARV_DEBUG_LEVEL_DEBUG); frame->error_packet_received = TRUE; thread_data->n_error_packets++; } else { /* Check for duplicated packets */ if (packet_id < frame->n_packets) { if (frame->packet_data[packet_id].received) thread_data->n_duplicated_packets++; else frame->packet_data[packet_id].received = TRUE; } /* Keep track of last packet of a continuous block starting from packet 0 */ for (i = frame->last_valid_packet + 1; i < frame->n_packets; i++) if (!frame->packet_data[i].received) break; frame->last_valid_packet = i - 1; switch (arv_gvsp_packet_get_content_type (packet)) { case ARV_GVSP_CONTENT_TYPE_DATA_LEADER: _process_data_leader (thread_data, frame, packet, packet_id); break; case ARV_GVSP_CONTENT_TYPE_DATA_BLOCK: _process_data_block (thread_data, frame, packet, packet_id, read_count); break; case ARV_GVSP_CONTENT_TYPE_DATA_TRAILER: _process_data_trailer (thread_data, frame, packet, packet_id); break; default: thread_data->n_ignored_packets++; break; } _missing_packet_check (thread_data, frame, packet_id, time_us); } } else thread_data->n_ignored_packets++; } else frame = NULL; _check_frame_completion (thread_data, time_us, frame); } while (!thread_data->cancel); _flush_frames (thread_data); if (thread_data->callback != NULL) thread_data->callback (thread_data->user_data, ARV_STREAM_CALLBACK_TYPE_EXIT, NULL); g_free (packet); return NULL; }
static gssize g_unix_input_stream_read (GInputStream *stream, void *buffer, gsize count, GCancellable *cancellable, GError **error) { GUnixInputStream *unix_stream; gssize res = -1; GPollFD poll_fds[2]; int nfds; int poll_ret; unix_stream = G_UNIX_INPUT_STREAM (stream); poll_fds[0].fd = unix_stream->priv->fd; poll_fds[0].events = G_IO_IN; if (unix_stream->priv->is_pipe_or_socket && g_cancellable_make_pollfd (cancellable, &poll_fds[1])) nfds = 2; else nfds = 1; while (1) { poll_fds[0].revents = poll_fds[1].revents = 0; do poll_ret = g_poll (poll_fds, nfds, -1); while (poll_ret == -1 && errno == EINTR); if (poll_ret == -1) { int errsv = errno; g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), _("Error reading from file descriptor: %s"), g_strerror (errsv)); break; } if (g_cancellable_set_error_if_cancelled (cancellable, error)) break; if (!poll_fds[0].revents) continue; res = read (unix_stream->priv->fd, buffer, count); if (res == -1) { int errsv = errno; if (errsv == EINTR || errsv == EAGAIN) continue; g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), _("Error reading from file descriptor: %s"), g_strerror (errsv)); } break; } if (nfds == 2) g_cancellable_release_fd (cancellable); return res; }
void * _thread (void *user_data) { ArvGvFakeCamera *gv_fake_camera = user_data; ArvBuffer *image_buffer = NULL; GError *error = NULL; GSocketAddress *stream_address = NULL; void *packet_buffer; size_t packet_size; size_t payload = 0; guint16 block_id; ptrdiff_t offset; guint32 gv_packet_size; GInputVector input_vector; int n_events; gboolean is_streaming = FALSE; input_vector.buffer = g_malloc0 (ARV_GV_FAKE_CAMERA_BUFFER_SIZE); input_vector.size = ARV_GV_FAKE_CAMERA_BUFFER_SIZE; packet_buffer = g_malloc (ARV_GV_FAKE_CAMERA_BUFFER_SIZE); do { guint64 next_timestamp_us; guint64 sleep_time_us; if (is_streaming) { sleep_time_us = arv_fake_camera_get_sleep_time_for_next_frame (gv_fake_camera->priv->camera, &next_timestamp_us); } else { sleep_time_us = 100000; next_timestamp_us = g_get_real_time () + sleep_time_us; } do { gint timeout_ms; timeout_ms = MIN (100, (next_timestamp_us - g_get_real_time ()) / 1000LL); if (timeout_ms < 0) timeout_ms = 0; n_events = g_poll (gv_fake_camera->priv->gvcp_fds, 2, timeout_ms); if (n_events > 0) { GSocketAddress *remote_address = NULL; int count; count = g_socket_receive_message (gv_fake_camera->priv->gvcp_socket, &remote_address, &input_vector, 1, NULL, NULL, NULL, NULL, NULL); if (count > 0) { if (handle_control_packet (gv_fake_camera, gv_fake_camera->priv->gvcp_socket, remote_address, input_vector.buffer, count)) arv_debug_device ("[GvFakeCamera::thread] Control packet received"); } g_clear_object (&remote_address); if (gv_fake_camera->priv->discovery_socket != NULL) { count = g_socket_receive_message (gv_fake_camera->priv->discovery_socket, &remote_address, &input_vector, 1, NULL, NULL, NULL, NULL, NULL); if (count > 0) { if (handle_control_packet (gv_fake_camera, gv_fake_camera->priv->discovery_socket, remote_address, input_vector.buffer, count)) arv_debug_device ("[GvFakeCamera::thread]" " Control packet received on discovery socket\n"); } g_clear_object (&remote_address); } if (arv_fake_camera_get_control_channel_privilege (gv_fake_camera->priv->camera) == 0 || arv_fake_camera_get_acquisition_status (gv_fake_camera->priv->camera) == 0) { if (stream_address != NULL) { g_object_unref (stream_address); stream_address = NULL; g_object_unref (image_buffer); image_buffer = NULL; arv_debug_stream_thread ("[GvFakeCamera::thread] Stop stream"); } is_streaming = FALSE; } } } while (!g_atomic_int_get (&gv_fake_camera->priv->cancel) && g_get_real_time () < next_timestamp_us); if (arv_fake_camera_get_control_channel_privilege (gv_fake_camera->priv->camera) != 0 && arv_fake_camera_get_acquisition_status (gv_fake_camera->priv->camera) != 0) { if (stream_address == NULL) { GInetAddress *inet_address; char *inet_address_string; stream_address = arv_fake_camera_get_stream_address (gv_fake_camera->priv->camera); inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (stream_address)); inet_address_string = g_inet_address_to_string (inet_address); arv_debug_stream_thread ("[GvFakeCamera::thread] Start stream to %s (%d)", inet_address_string, g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (stream_address))); g_free (inet_address_string); payload = arv_fake_camera_get_payload (gv_fake_camera->priv->camera); image_buffer = arv_buffer_new (payload, NULL); } arv_fake_camera_fill_buffer (gv_fake_camera->priv->camera, image_buffer, &gv_packet_size); arv_debug_stream_thread ("[GvFakeCamera::thread] Send frame %d", image_buffer->priv->frame_id); block_id = 0; packet_size = ARV_GV_FAKE_CAMERA_BUFFER_SIZE; arv_gvsp_packet_new_data_leader (image_buffer->priv->frame_id, block_id, image_buffer->priv->timestamp_ns, image_buffer->priv->pixel_format, image_buffer->priv->width, image_buffer->priv->height, image_buffer->priv->x_offset, image_buffer->priv->y_offset, packet_buffer, &packet_size); g_socket_send_to (gv_fake_camera->priv->gvsp_socket, stream_address, packet_buffer, packet_size, NULL, &error); if (error != NULL) { arv_warning_stream_thread ("[GvFakeCamera::thread] Failed to send leader for frame %d: %s", image_buffer->priv->frame_id, error->message); g_clear_error (&error); } block_id++; offset = 0; while (offset < payload) { size_t data_size; data_size = MIN (gv_packet_size - ARV_GVSP_PACKET_PROTOCOL_OVERHEAD, payload - offset); packet_size = ARV_GV_FAKE_CAMERA_BUFFER_SIZE; arv_gvsp_packet_new_data_block (image_buffer->priv->frame_id, block_id, data_size, ((char *) image_buffer->priv->data) + offset, packet_buffer, &packet_size); g_socket_send_to (gv_fake_camera->priv->gvsp_socket, stream_address, packet_buffer, packet_size, NULL, &error); if (error != NULL) { arv_debug_stream_thread ("[GvFakeCamera::thread] Failed to send frame block %d for frame: %s", block_id, image_buffer->priv->frame_id, error->message); g_clear_error (&error); } offset += data_size; block_id++; } packet_size = ARV_GV_FAKE_CAMERA_BUFFER_SIZE; arv_gvsp_packet_new_data_trailer (image_buffer->priv->frame_id, block_id, packet_buffer, &packet_size); g_socket_send_to (gv_fake_camera->priv->gvsp_socket, stream_address, packet_buffer, packet_size, NULL, &error); if (error != NULL) { arv_debug_stream_thread ("[GvFakeCamera::thread] Failed to send trailer for frame %d: %s", image_buffer->priv->frame_id, error->message); g_clear_error (&error); } is_streaming = TRUE; } } while (!g_atomic_int_get (&gv_fake_camera->priv->cancel)); if (stream_address != NULL) g_object_unref (stream_address); if (image_buffer != NULL) g_object_unref (image_buffer); g_free (packet_buffer); g_free (input_vector.buffer); return NULL; }
static gboolean _read_memory (ArvGvDeviceIOData *io_data, guint32 address, guint32 size, void *buffer, GError **error) { ArvGvcpPacket *packet; size_t packet_size; size_t answer_size; int count; unsigned int n_retries = 0; gboolean success = FALSE; answer_size = arv_gvcp_packet_get_read_memory_ack_size (size); g_return_val_if_fail (answer_size <= ARV_GV_DEVICE_BUFFER_SIZE, FALSE); g_mutex_lock (io_data->mutex); packet = arv_gvcp_packet_new_read_memory_cmd (address, ((size + sizeof (guint32) - 1) / sizeof (guint32)) * sizeof (guint32), 0, &packet_size); do { io_data->packet_id = arv_gvcp_next_packet_id (io_data->packet_id); arv_gvcp_packet_set_packet_id (packet, io_data->packet_id); arv_gvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG); g_socket_send_to (io_data->socket, io_data->device_address, (const char *) packet, packet_size, NULL, NULL); if (g_poll (&io_data->poll_in_event, 1, io_data->gvcp_timeout_ms) > 0) { count = g_socket_receive (io_data->socket, io_data->buffer, ARV_GV_DEVICE_BUFFER_SIZE, NULL, NULL); if (count >= answer_size) { ArvGvcpPacket *ack_packet = io_data->buffer; ArvGvcpPacketType packet_type; ArvGvcpCommand command; guint16 packet_id; arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_LOG); packet_type = arv_gvcp_packet_get_packet_type (ack_packet); command = arv_gvcp_packet_get_command (ack_packet); packet_id = arv_gvcp_packet_get_packet_id (ack_packet); if (packet_type == ARV_GVCP_PACKET_TYPE_ACK && command == ARV_GVCP_COMMAND_READ_MEMORY_ACK && packet_id == io_data->packet_id) { memcpy (buffer, arv_gvcp_packet_get_read_memory_ack_data (ack_packet), size); success = TRUE; } else arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_WARNING); } } n_retries++; } while (!success && n_retries < io_data->gvcp_n_retries); arv_gvcp_packet_free (packet); g_mutex_unlock (io_data->mutex); if (!success) { if (error != NULL && *error == NULL) *error = g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_STATUS_TIMEOUT, "[ArvDevice::read_memory] Timeout"); } return success; }
gboolean _write_register (ArvGvDeviceIOData *io_data, guint32 address, guint32 value, GError **error) { ArvGvcpPacket *packet; size_t packet_size; int count; unsigned int n_retries = 0; gboolean success = FALSE; g_mutex_lock (io_data->mutex); packet = arv_gvcp_packet_new_write_register_cmd (address, value, io_data->packet_id, &packet_size); do { io_data->packet_id = arv_gvcp_next_packet_id (io_data->packet_id); arv_gvcp_packet_set_packet_id (packet, io_data->packet_id); arv_gvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG); g_socket_send_to (io_data->socket, io_data->device_address, (const char *) packet, packet_size, NULL, NULL); if (g_poll (&io_data->poll_in_event, 1, io_data->gvcp_timeout_ms) > 0) { count = g_socket_receive (io_data->socket, io_data->buffer, ARV_GV_DEVICE_BUFFER_SIZE, NULL, NULL); if (count > 0) { ArvGvcpPacket *ack_packet = io_data->buffer; ArvGvcpPacketType packet_type; ArvGvcpCommand command; guint16 packet_id; arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_LOG); packet_type = arv_gvcp_packet_get_packet_type (ack_packet); command = arv_gvcp_packet_get_command (ack_packet); packet_id = arv_gvcp_packet_get_packet_id (ack_packet); arv_log_gvcp ("%d, %d, %d", packet_type, command, packet_id); if (packet_type == ARV_GVCP_PACKET_TYPE_ACK && command == ARV_GVCP_COMMAND_WRITE_REGISTER_ACK && packet_id == io_data->packet_id) success = TRUE; else arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_WARNING); } } n_retries++; } while (!success && n_retries < io_data->gvcp_n_retries); arv_gvcp_packet_free (packet); g_mutex_unlock (io_data->mutex); if (!success) { if (error != NULL && *error == NULL) *error = g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_STATUS_TIMEOUT, "[ArvDevice::write_register] Timeout"); } return success; }
static gboolean g_unix_output_stream_writev (GOutputStream *stream, const GOutputVector *vectors, gsize n_vectors, gsize *bytes_written, GCancellable *cancellable, GError **error) { GUnixOutputStream *unix_stream; gssize res = -1; GPollFD poll_fds[2]; int nfds = 0; int poll_ret; struct iovec *iov; if (bytes_written) *bytes_written = 0; /* Clamp to G_MAXINT as writev() takes an integer for the number of vectors. * We handle this like a short write in this case */ if (n_vectors > G_MAXINT) n_vectors = G_MAXINT; unix_stream = G_UNIX_OUTPUT_STREAM (stream); if (G_OUTPUT_VECTOR_IS_IOVEC) { /* ABI is compatible */ iov = (struct iovec *) vectors; } else { gsize i; /* ABI is incompatible */ iov = g_newa (struct iovec, n_vectors); for (i = 0; i < n_vectors; i++) { iov[i].iov_base = (void *)vectors[i].buffer; iov[i].iov_len = vectors[i].size; } } poll_fds[0].fd = unix_stream->priv->fd; poll_fds[0].events = G_IO_OUT; nfds++; if (unix_stream->priv->is_pipe_or_socket && g_cancellable_make_pollfd (cancellable, &poll_fds[1])) nfds++; while (1) { int errsv; poll_fds[0].revents = poll_fds[1].revents = 0; do { poll_ret = g_poll (poll_fds, nfds, -1); errsv = errno; } while (poll_ret == -1 && errsv == EINTR); if (poll_ret == -1) { g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), _("Error writing to file descriptor: %s"), g_strerror (errsv)); break; } if (g_cancellable_set_error_if_cancelled (cancellable, error)) break; if (!poll_fds[0].revents) continue; res = writev (unix_stream->priv->fd, iov, n_vectors); errsv = errno; if (res == -1) { if (errsv == EINTR || errsv == EAGAIN) continue; g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), _("Error writing to file descriptor: %s"), g_strerror (errsv)); } if (bytes_written) *bytes_written = res; break; } if (nfds == 2) g_cancellable_release_fd (cancellable); return res != -1; }
static void arv_gv_interface_discover (ArvGvInterface *gv_interface) { ArvGvDiscoverSocketList *socket_list; GSList *iter; char buffer[ARV_GV_INTERFACE_SOCKET_BUFFER_SIZE]; int count; int i; socket_list = arv_gv_discover_socket_list_new (); if (socket_list->n_sockets < 1) { arv_gv_discover_socket_list_free (socket_list); return; } arv_gv_discover_socket_list_send_discover_packet (socket_list); do { if (g_poll (socket_list->poll_fds, socket_list->n_sockets, ARV_GV_INTERFACE_DISCOVERY_TIMEOUT_MS) == 0) { arv_gv_discover_socket_list_free (socket_list); return; } for (i = 0, iter = socket_list->sockets; iter != NULL; i++, iter = iter->next) { ArvGvDiscoverSocket *discover_socket = iter->data; do { g_socket_set_blocking (discover_socket->socket, FALSE); count = g_socket_receive (discover_socket->socket, buffer, ARV_GV_INTERFACE_SOCKET_BUFFER_SIZE, NULL, NULL); g_socket_set_blocking (discover_socket->socket, TRUE); if (count > 0) { ArvGvcpPacket *packet = (ArvGvcpPacket *) buffer; if (g_ntohs (packet->header.command) == ARV_GVCP_COMMAND_DISCOVERY_ACK && g_ntohs (packet->header.id) == 0xffff) { ArvGvInterfaceDeviceInfos *device_infos; GInetAddress *interface_address; char *address_string; char *data = buffer + sizeof (ArvGvcpHeader); arv_gvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG); interface_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (discover_socket->interface_address)); device_infos = arv_gv_interface_device_infos_new (interface_address, data); address_string = g_inet_address_to_string (interface_address); arv_debug_interface ("[GvInterface::discovery] Device '%s' found " "(interface %s) user_name '%s' - MAC_name '%s'", device_infos->name, address_string, device_infos->user_name, device_infos->mac_string); g_free (address_string); if (device_infos->name != NULL && device_infos->name[0] != '\0') { arv_gv_interface_device_infos_ref (device_infos); g_hash_table_insert (gv_interface->priv->devices, device_infos->name, device_infos); } if (device_infos->user_name != NULL && device_infos->user_name[0] != '\0') { arv_gv_interface_device_infos_ref (device_infos); g_hash_table_insert (gv_interface->priv->devices, device_infos->user_name, device_infos); } arv_gv_interface_device_infos_ref (device_infos); g_hash_table_insert (gv_interface->priv->devices, device_infos->mac_string, device_infos); arv_gv_interface_device_infos_unref (device_infos); } } } while (count > 0); } } while (1); }
int main (int argc, char **argv) { ArvFakeGvCamera *gv_camera; int n_events; GInputVector input_vector; GOptionContext *context; GError *error = NULL; arv_g_thread_init (NULL); arv_g_type_init (); context = g_option_context_new (NULL); g_option_context_set_summary (context, "Fake GigEVision camera."); g_option_context_set_description (context, "Example: 'arv-fake-gv-camera-" ARAVIS_API_VERSION " -i eth0'"); g_option_context_add_main_entries (context, arv_option_entries, NULL); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_option_context_free (context); g_print ("Option parsing failed: %s\n", error->message); g_error_free (error); return EXIT_FAILURE; } g_option_context_free (context); arv_debug_enable (arv_option_debug_domains); gv_camera = arv_fake_gv_camera_new (arv_option_interface_name); if (gv_camera == NULL) { g_print ("Can't instantiate a new fake camera.\n"); g_print ("An existing instance may already use the '%s' interface.\n", arv_option_interface_name); return EXIT_FAILURE; } input_vector.buffer = g_malloc0 (ARV_FAKE_GV_CAMERA_BUFFER_SIZE); input_vector.size = ARV_FAKE_GV_CAMERA_BUFFER_SIZE; signal (SIGINT, set_cancel); do { n_events = g_poll (gv_camera->gvcp_fds, 2, 1000); g_print ("n_events = %d\n", n_events); if (n_events > 0) { GSocketAddress *remote_address; int count; count = g_socket_receive_message (gv_camera->gvcp_socket, &remote_address, &input_vector, 1, NULL, NULL, G_SOCKET_MSG_NONE, NULL, NULL); if (count > 0) handle_control_packet (gv_camera, gv_camera->gvcp_socket, remote_address, input_vector.buffer, count); if (gv_camera->discovery_socket != NULL) { count = g_socket_receive_message (gv_camera->discovery_socket, &remote_address, &input_vector, 1, NULL, NULL, G_SOCKET_MSG_NONE, NULL, NULL); if (count > 0) handle_control_packet (gv_camera, gv_camera->discovery_socket, remote_address, input_vector.buffer, count); } } } while (!cancel); g_free (input_vector.buffer); arv_fake_gv_camera_free (gv_camera); return EXIT_SUCCESS; }