static int worker_thread(void *arg) { pj_sock_t sock = (pj_sock_t)arg; char buf[512]; pj_status_t last_recv_err = PJ_SUCCESS, last_write_err = PJ_SUCCESS; while (!thread_quit_flag) { pj_ssize_t len; pj_status_t rc; pj_sockaddr_in addr; int addrlen; len = sizeof(buf); addrlen = sizeof(addr); rc = pj_sock_recvfrom(sock, buf, &len, 0, &addr, &addrlen); if (rc != 0) { if (rc != last_recv_err) { app_perror("...recv error", rc); last_recv_err = rc; } continue; } pj_atomic_add(total_bytes, (pj_atomic_value_t)len); rc = pj_sock_sendto(sock, buf, &len, 0, &addr, addrlen); if (rc != PJ_SUCCESS) { if (rc != last_write_err) { app_perror("...send error", rc); last_write_err = rc; } continue; } } return 0; }
static void on_read_complete(pj_ioqueue_key_t *key, pj_ioqueue_op_key_t *op_key, pj_ssize_t bytes_received) { pj_status_t rc; struct op_key *recv_rec = (struct op_key *)op_key; for (;;) { struct op_key *send_rec = recv_rec->peer; recv_rec->is_pending = 0; if (bytes_received < 0) { if (-bytes_received != recv_rec->last_err) { recv_rec->last_err = (pj_status_t)-bytes_received; app_perror("...error receiving data", recv_rec->last_err); } } else if (bytes_received == 0) { /* note: previous error, or write callback */ } else { pj_atomic_add(total_bytes, (pj_atomic_value_t)bytes_received); if (!send_rec->is_pending) { pj_ssize_t sent = bytes_received; pj_memcpy(send_rec->buffer, recv_rec->buffer, bytes_received); pj_memcpy(&send_rec->addr, &recv_rec->addr, recv_rec->addrlen); send_rec->addrlen = recv_rec->addrlen; rc = pj_ioqueue_sendto(key, &send_rec->op_key_, send_rec->buffer, &sent, 0, &send_rec->addr, send_rec->addrlen); send_rec->is_pending = (rc==PJ_EPENDING); if (rc!=PJ_SUCCESS && rc!=PJ_EPENDING) { app_perror("...send error(1)", rc); } } } if (!send_rec->is_pending) { bytes_received = recv_rec->size; rc = pj_ioqueue_recvfrom(key, &recv_rec->op_key_, recv_rec->buffer, &bytes_received, 0, &recv_rec->addr, &recv_rec->addrlen); recv_rec->is_pending = (rc==PJ_EPENDING); if (rc == PJ_SUCCESS) { /* fall through next loop. */ } else if (rc == PJ_EPENDING) { /* quit callback. */ break; } else { /* error */ app_perror("...recv error", rc); recv_rec->last_err = rc; bytes_received = 0; /* fall through next loop. */ } } else { /* recv will be done when write completion callback is called. */ break; } } }
// // Add the variable. // void add(pj_atomic_value_t value) { pj_atomic_add(var_, value); }