void zmq::tcp_connecter_t::out_event () { if (connect_timer_started) { cancel_timer (connect_timer_id); connect_timer_started = false; } rm_handle (); const fd_t fd = connect (); // Handle the error condition by attempt to reconnect. if (fd == retired_fd || !tune_socket (fd)) { close (); add_reconnect_timer (); return; } // Create the engine object for this connection. stream_engine_t *engine = new (std::nothrow) stream_engine_t (fd, options, endpoint); alloc_assert (engine); // Attach the engine to the corresponding session object. send_attach (session, engine); // Shut the connecter down. terminate (); socket->event_connected (endpoint, (int) fd); }
void zmq::tcp_connecter_t::timer_event (int id_) { zmq_assert (id_ == reconnect_timer_id || id_ == connect_timer_id); if (id_ == connect_timer_id) { connect_timer_started = false; rm_handle (); close (); add_reconnect_timer (); } else if (id_ == reconnect_timer_id) { reconnect_timer_started = false; start_connecting (); } }
static bool close_handle(int handle_id) { struct memory_handle *h = find_handle(handle_id); /* If the handle is not found, it is closed */ if (!h) return true; if (h->fd >= 0) { close(h->fd); h->fd = -1; } /* rm_handle returns true unless the handle somehow persists after exit */ return rm_handle(h); }
void zmq::tcp_connecter_t::process_term (int linger_) { if (connect_timer_started) { cancel_timer (connect_timer_id); connect_timer_started = false; } if (reconnect_timer_started) { cancel_timer (reconnect_timer_id); reconnect_timer_started = false; } if (handle) { rm_handle (); } if (s != retired_fd) close (); own_t::process_term (linger_); }
/* Reserve space in the buffer for a file. filename: name of the file to open offset: offset at which to start buffering the file, useful when the first (offset-1) bytes of the file aren't needed. type: one of the data types supported (audio, image, cuesheet, others user_data: user data passed possibly passed in subcalls specific to a data_type (only used for image (albumart) buffering so far ) return value: <0 if the file cannot be opened, or one file already queued to be opened, otherwise the handle for the file in the buffer */ int bufopen(const char *file, size_t offset, enum data_type type, void *user_data) { #ifndef HAVE_ALBUMART /* currently only used for aa loading */ (void)user_data; #endif if (type == TYPE_ID3) { /* ID3 case: allocate space, init the handle and return. */ struct memory_handle *h = add_handle(sizeof(struct mp3entry), false, true); if (!h) return ERR_BUFFER_FULL; h->fd = -1; h->filesize = sizeof(struct mp3entry); h->filerem = sizeof(struct mp3entry); h->offset = 0; h->data = buf_widx; h->ridx = buf_widx; h->widx = buf_widx; h->available = 0; h->type = type; strlcpy(h->path, file, MAX_PATH); buf_widx += sizeof(struct mp3entry); /* safe because the handle can't wrap */ /* Inform the buffering thread that we added a handle */ LOGFQUEUE("buffering > Q_HANDLE_ADDED %d", h->id); queue_post(&buffering_queue, Q_HANDLE_ADDED, h->id); return h->id; } /* Other cases: there is a little more work. */ int fd = open(file, O_RDONLY); if (fd < 0) return ERR_FILE_ERROR; size_t size = filesize(fd); bool can_wrap = type==TYPE_PACKET_AUDIO || type==TYPE_CODEC; size_t adjusted_offset = offset; if (adjusted_offset > size) adjusted_offset = 0; /* Reserve extra space because alignment can move data forward */ size_t padded_size = STORAGE_PAD(size-adjusted_offset); struct memory_handle *h = add_handle(padded_size, can_wrap, false); if (!h) { DEBUGF("%s(): failed to add handle\n", __func__); close(fd); return ERR_BUFFER_FULL; } strlcpy(h->path, file, MAX_PATH); h->offset = adjusted_offset; /* Don't bother to storage align bitmaps because they are not * loaded directly into the buffer. */ if (type != TYPE_BITMAP) { size_t alignment_pad; /* Remember where data area starts, for use by reset_handle */ h->start = buf_widx; /* Align to desired storage alignment */ alignment_pad = STORAGE_OVERLAP(adjusted_offset - (size_t)(&buffer[buf_widx])); buf_widx = ringbuf_add(buf_widx, alignment_pad); } h->ridx = buf_widx; h->widx = buf_widx; h->data = buf_widx; h->available = 0; h->filerem = 0; h->type = type; #ifdef HAVE_ALBUMART if (type == TYPE_BITMAP) { /* Bitmap file: we load the data instead of the file */ int rc; mutex_lock(&llist_mod_mutex); /* Lock because load_bitmap yields */ rc = load_image(fd, file, (struct dim*)user_data); mutex_unlock(&llist_mod_mutex); if (rc <= 0) { rm_handle(h); close(fd); return ERR_FILE_ERROR; } h->filerem = 0; h->filesize = rc; h->available = rc; h->widx = buf_widx + rc; /* safe because the data doesn't wrap */ buf_widx += rc; /* safe too */ } else #endif { h->filerem = size - adjusted_offset; h->filesize = size; h->available = 0; h->widx = buf_widx; } if (type == TYPE_CUESHEET) { h->fd = fd; /* Immediately start buffering those */ LOGFQUEUE("buffering >| Q_BUFFER_HANDLE %d", h->id); queue_send(&buffering_queue, Q_BUFFER_HANDLE, h->id); } else { /* Other types will get buffered in the course of normal operations */ h->fd = -1; close(fd); /* Inform the buffering thread that we added a handle */ LOGFQUEUE("buffering > Q_HANDLE_ADDED %d", h->id); queue_post(&buffering_queue, Q_HANDLE_ADDED, h->id); } logf("bufopen: new hdl %d", h->id); return h->id; }