// |buffer******|end--------------|start**************|bufferEnd // |buffer-----|start**************|end---------------|bufferEnd int Pipe::size() { int res; /* size macro allocates the result variable by itself */ lock(); _SIZE(res); unlock(); return res; }
static void ril_state_init(RilState* rilState) { D("%s", __FUNCTION__); rilState->init = 0; rilState->control[0] = -1; rilState->control[1] = -1; rilState->fd = -1; rilState->lbs = NULL; rilState->local_path = BRCM_LOCAL_PATH; timeout_action_init(ta_conn_retry, _SIZE(ta_conn_retry)); return; }
int Pipe::read(int length, void *data) { int worklen, origlen, truelen; int blk, len, buffered, buffered_bytes; int ttl = 0; if(read_blocking) ttl = read_blocking_time; lock(); _SIZE(buffered_bytes); buffered = buffered_bytes / read_copy_cb->src_samplesize; truelen = length; while(buffered<length) { /* if less than desired is in, then (blocking) waits (non blocking) returns what's available */ if(read_blocking) { unlock(); if(!ttl) { return -1; } jsleep(0,sleep_time*1000); ttl -= sleep_time; lock(); _SIZE(buffered_bytes); buffered = buffered_bytes / read_copy_cb->src_samplesize; } else { // nothing in the pipe if(!buffered) { unlock(); return 0; } else truelen = buffered; break; } } origlen = worklen = truelen * read_copy_cb->src_samplesize; while (worklen) { /* |buffer*****|end-----------|start********|bufferEnd |buffer-----|start*********|end----------|bufferEnd */ len = MIN(worklen,buffered_bytes); blk = ((char*)bufferEnd - (char*)start); blk=MIN(blk,len); /* fill */ (*read_copy_cb->callback) (data, start, blk / read_copy_cb->src_samplesize); /* blank just copied bytes */ //memset(start,0,blk / read_copy_cb->src_samplesize); start = &((char*)start)[blk]; // (char*)start += blk; len -= blk; data = &((char*)data)[blk]; // (char*)data += blk; worklen -= blk; if ((end!=buffer) && (start==bufferEnd)) start = buffer; if (len) { /* short circuit */ (*read_copy_cb->callback) (data, start, len / read_copy_cb->src_samplesize); // /* blank just copied bytes */ // memset(start,0,len / read_copy_cb->src_samplesize); data = &((char*)data)[len]; // (char*)data += len; start = &((char*)start)[len]; // (char*)start += len; worklen -= len; if ((end!=buffer) && (start==bufferEnd)) start = buffer; } } if (start == end) /* if this read emptied buffer */ start = end = buffer; /* reset pointers to le _SIZE behave correctly */ unlock(); return ( (origlen-worklen)/read_copy_cb->src_samplesize ); }
static void* ril_state_thread(void* arg) { int started = 0; RilState* rilState = (RilState*) arg; int ril_fd = rilState->fd; int control_fd = rilState->control[1]; D("RIL LCSAPI thread running"); ril_lcsapi_init(rilState); for (;;) { struct pollfd pfd[2]; int nfds; int nevents; unsigned int ne; int timeoutms = -1; memset(pfd, 0, sizeof(pfd)); timeout_action_update_timeouts(ta_conn_retry, _SIZE(ta_conn_retry)); if (rilState->fd < 0) { // Waiting a constant time isn't the best solution because // 1. In the case where LCS socket is matching, less waiting is better. // The booting time is smaller. // 2. In the case where LCS socket is mismatching due to integration failure, // it causes unexpected flood of warnings. D("ril_state_thread, fd < 0, calling timeout_action_add"); timeout_action_add(ta_conn_retry, _SIZE(ta_conn_retry), 0, wait_time_get(), connect_init_cb, rilState); } else { D("ril_state_thread, fd = %d", rilState->fd); nfds = poll_register_in(pfd, _SIZE(pfd), rilState->fd); // Resets the LCS socket waiting time so next connection loss won't wait for long. wait_time_reset(); } if (timeout_action_any_inuse(ta_conn_retry, _SIZE(ta_conn_retry))) { timeoutms = 1000; } // register control file descriptors for polling nfds = poll_register_in(pfd, _SIZE(pfd), control_fd ); nevents = poll(pfd, nfds, timeoutms); if (nevents < 0) { if (errno != EINTR) { LOGE("poll unexpected error: %s", strerror(errno)); } continue; } D("ril thread received %d events", nevents); if (nevents == 0) { continue; } for (ne=0; ne<_SIZE(pfd); ne++) { if ((pfd[ne].fd == rilState->fd) && (pfd[ne].revents & (POLLERR | POLLHUP)) != 0) { LOGE("EPOLLERR or EPOLLHUP after poll() !?"); ril_state_done(rilState); continue; } if (pfd[ne].revents & POLLIN) { int fd = pfd[ne].fd; if (fd == control_fd) { struct ril_cmds cmd; int ret; D("ril control fd event"); do { ret = read( fd, &cmd, sizeof(cmd)); } while (ret < 0 && errno == EINTR); if (ret == sizeof(cmd)) { if (cmd.id == CMD_DEINIT) { goto Exit; } else { process_cmds(rilState, &cmd); } } else if (ret < 0) { D("Error reading command %d", errno); } else { D("Not proper size"); } } else if (fd == rilState->fd) { D("gps fd event"); BrcmLbs_processMessages(rilState->lbs, BRCMLBS_RX); } else { LOGE("poll() returned unkown fd %d ?", fd); } } } } Exit: D("Exiting ril thread"); ril_state_done(rilState); return NULL; }