int zmq::v2_decoder_t::size_ready(uint64_t msg_size, unsigned char const* read_pos) { // Message size must not exceed the maximum allowed size. if (maxmsgsize >= 0) if (unlikely (msg_size > static_cast <uint64_t> (maxmsgsize))) { errno = EMSGSIZE; return -1; } // Message size must fit into size_t data type. if (unlikely (msg_size != static_cast <size_t> (msg_size))) { errno = EMSGSIZE; return -1; } // in_progress is initialised at this point so in theory we should // close it before calling init_size, however, it's a 0-byte // message and thus we can treat it as uninitialised. int rc = -1; // the current message can exceed the current buffer. We have to copy the buffer // data into a new message and complete it in the next receive. if (unlikely ((unsigned char*)read_pos + msg_size > (data() + size()))) { // a new message has started, but the size would exceed the pre-allocated arena // this happens everytime when a message does not fit completely into the buffer rc = in_progress.init_size (static_cast <size_t> (msg_size)); } else { // construct message using n bytes from the buffer as storage // increase buffer ref count rc = in_progress.init( (unsigned char*)read_pos, msg_size, shared_message_memory_allocator::call_dec_ref, buffer() ); // For small messages, data has been copied and refcount does not have to be increased if (in_progress.is_lmsg()) { inc_ref(); } } if (unlikely (rc)) { errno_assert (errno == ENOMEM); rc = in_progress.init (); errno_assert (rc == 0); errno = ENOMEM; return -1; } in_progress.set_flags (msg_flags); // this sets read_pos to // the message data address if the data needs to be copied // for small message / messages exceeding the current buffer // or // to the current start address in the buffer because the message // was constructed to use n bytes from the address passed as argument next_step (in_progress.data (), in_progress.size (), &v2_decoder_t::message_ready); return 0; }
Callable(ObjP o) : type(OBJECT), obj(o) { inc_ref(obj); }
void operator=(const Callable& c) { memcpy(this, &c, sizeof(*this)); if (type == OBJECT) inc_ref(obj); }
static void inc_ref(mblk_t*m){ m->b_datap->db_ref++; if (m->b_cont) inc_ref(m->b_cont); }
static int msv4l2_do_mmap(V4l2State *s){ struct v4l2_requestbuffers req; int i; enum v4l2_buf_type type; memset(&req,0,sizeof(req)); req.count = 4; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; if (v4l2_ioctl (s->fd, VIDIOC_REQBUFS, &req)<0) { ms_error("Error requesting info on mmap'd buffers: %s",strerror(errno)); return -1; } for (i=0; i<req.count; ++i) { struct v4l2_buffer buf; mblk_t *msg; void *start; memset(&buf,0,sizeof(buf)); buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory=V4L2_MEMORY_MMAP; buf.index=i; if (v4l2_ioctl (s->fd, VIDIOC_QUERYBUF, &buf)<0){ ms_error("Could not VIDIOC_QUERYBUF : %s",strerror(errno)); return -1; } start=v4l2_mmap (NULL /* start anywhere */, buf.length, PROT_READ | PROT_WRITE /* required */, MAP_SHARED /* recommended */, s->fd, buf.m.offset); if (start==NULL){ ms_error("Could not v4l2_mmap: %s",strerror(errno)); } msg=esballoc(start,buf.length,0,NULL); msg->b_wptr+=buf.length; s->frames[i]=ms_yuv_buf_alloc_from_buffer(s->vsize.width, s->vsize.height, msg); } s->frame_max=req.count; for (i = 0; i < s->frame_max; ++i) { struct v4l2_buffer buf; memset(&buf,0,sizeof(buf)); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (-1==v4l2_ioctl (s->fd, VIDIOC_QBUF, &buf)){ ms_error("VIDIOC_QBUF failed: %s",strerror(errno)); }else { inc_ref(s->frames[i]); s->queued++; } } /*start capture immediately*/ type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 ==v4l2_ioctl (s->fd, VIDIOC_STREAMON, &type)){ ms_error("VIDIOC_STREAMON failed: %s",strerror(errno)); return -1; } return 0; }
static int impl_dummy_server(void) { int dummy_server = -1; /* Create our dummy sock. */ struct sockaddr_un dummy_addr; char *socket_path = tempnam("/tmp", ".huptime"); memset(&dummy_addr, 0, sizeof(struct sockaddr_un)); dummy_addr.sun_family = AF_UNIX; strncpy(dummy_addr.sun_path, socket_path, sizeof(dummy_addr.sun_path)-1); /* Create a dummy server. */ dummy_server = socket(AF_UNIX, SOCK_STREAM, 0); if( dummy_server < 0 ) { fprintf(stderr, "Unable to create unix socket?"); return -1; } if( fcntl(dummy_server, F_SETFD, FD_CLOEXEC) < 0 ) { close(dummy_server); fprintf(stderr, "Unable to set cloexec?"); return -1; } if( libc.bind( dummy_server, (struct sockaddr*)&dummy_addr, sizeof(struct sockaddr_un)) < 0 ) { close(dummy_server); fprintf(stderr, "Unable to bind unix socket?"); return -1; } if( libc.listen(dummy_server, 1) < 0 ) { close(dummy_server); fprintf(stderr, "Unable to listen on unix socket?"); return -1; } /* Connect a dummy client. */ int dummy_client = socket(AF_UNIX, SOCK_STREAM, 0); if( dummy_client < 0 ) { close(dummy_server); fprintf(stderr, "Unable to create unix socket?"); return -1; } if( fcntl(dummy_client, F_SETFD, FD_CLOEXEC) < 0 ) { close(dummy_server); close(dummy_client); fprintf(stderr, "Unable to set cloexec?"); return -1; } if( connect( dummy_client, (struct sockaddr*)&dummy_addr, sizeof(struct sockaddr_un)) < 0 ) { close(dummy_server); close(dummy_client); fprintf(stderr, "Unable to connect dummy client?"); return -1; } /* Put the client into an error state. */ int dummy_fd = libc.accept(dummy_server, NULL, 0); if( dummy_fd < 0 ) { fprintf(stderr, "Unable to accept internal client?"); close(dummy_server); close(dummy_client); return -1; } close(dummy_fd); /* Save the dummy info. */ fdinfo_t* dummy_info = alloc_info(DUMMY); if( dummy_info == NULL ) { fprintf(stderr, "Unable to allocate dummy info?"); return -1; } dummy_info->dummy.client = dummy_client; fd_save(dummy_server, dummy_info); inc_ref(dummy_info); fd_save(dummy_client, dummy_info); /* Ensure that it's unlinked. */ unlink(socket_path); free(socket_path); return dummy_server; }
static int do_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) { int rval = -1; fdinfo_t *info = NULL; if( sockfd < 0 ) { errno = EINVAL; return -1; } DEBUG("do_accept4(%d, ...) ...", sockfd); L(); info = fd_lookup(sockfd); if( info == NULL || (info->type != BOUND && info->type != DUMMY) ) { U(); /* Should return an error. */ rval = libc.accept4(sockfd, addr, addrlen, flags); DEBUG("do_accept4(%d, ...) => %d (no info)", sockfd, rval); return rval; } /* Check that they've called listen. */ if( info->type == BOUND && !info->bound.stub_listened ) { U(); DEBUG("do_accept4(%d, ...) => -1 (not listened)", sockfd); errno = EINVAL; return -1; } /* Check if this is a dummy. * There's no way that they should be calling accept(). * The dummy FD will never trigger a poll, select, epoll, * etc. So we just act as a socket with no clients does -- * either return immediately or block forever. NOTE: We * still return in case of EINTR or other suitable errors. */ if( info->type == DUMMY && info->dummy.client >= 0 ) { rval = info->dummy.client; info->dummy.client = -1; U(); DEBUG("do_accept4(%d, ...) => %d (dummy client)", sockfd, rval); return rval; } U(); if( !(flags & SOCK_NONBLOCK) ) { /* Wait for activity on the socket. */ struct pollfd poll_info; poll_info.fd = sockfd; poll_info.events = POLLIN; poll_info.revents = 0; if( poll(&poll_info, 1, -1) < 0 ) { return -1; } } L(); /* Check our status. */ if( is_exiting == TRUE ) { /* We've transitioned from not exiting * to exiting in this period. This will * circle around a return a dummy descriptor. */ U(); DEBUG("do_accept4(%d, ...) => -1 (interrupted)", sockfd); errno = flags & SOCK_NONBLOCK ? EAGAIN : EINTR; return -1; } /* Do the accept for real. */ fdinfo_t *new_info = alloc_info(TRACKED); if( new_info == NULL ) { U(); DEBUG("do_accept4(%d, ...) => -1 (alloc error?)", sockfd); return -1; } inc_ref(info); new_info->tracked.bound = info; rval = libc.accept4(sockfd, addr, addrlen, flags); if( rval >= 0 ) { /* Save the reference to the socket. */ fd_save(rval, new_info); } else { /* An error occured, nothing to track. */ dec_ref(new_info); } U(); DEBUG("do_accept4(%d, ...) => %d (tracked %d) %s", sockfd, rval, total_tracked, rval == -1 ? strerror(errno) : ""); return rval; }
void Future::run_callback_on_work_thread() { inc_ref(); // Keep the future alive for the callback work_.data = this; uv_queue_work(loop_.load(), &work_, on_work, on_after_work); }