aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric <ewild@sysmocom.de>2020-07-17 20:46:25 +0200
committerEric <ewild@sysmocom.de>2020-08-26 17:35:18 +0200
commit056c5d8fab676340873a5a8327a3ac669734f6ee (patch)
tree71cbd75575e78a53b28644f3d8f175884fb82fb4
parentdevices: reset internal smart sample buffers upon stop (diff)
downloadOsmoTRX-056c5d8fab676340873a5a8327a3ac669734f6ee.tar.xz
OsmoTRX-056c5d8fab676340873a5a8327a3ac669734f6ee.zip
ipc: manually poll chan sock fds
We can't wait, we're in select, but we need to wait for a response from the other side of the ipc interface -> only select our channels, so other registered osmo fds are left alone, and we don't accidentally handle stuff that should happen afterwards. Change-Id: I4ffc8d825e5b4eba0fca8ea821b1d84e2b923266
-rw-r--r--Transceiver52M/device/ipc/IPCDevice.cpp78
-rw-r--r--Transceiver52M/device/ipc/IPCDevice.h1
2 files changed, 62 insertions, 17 deletions
diff --git a/Transceiver52M/device/ipc/IPCDevice.cpp b/Transceiver52M/device/ipc/IPCDevice.cpp
index febd668..b1a747c 100644
--- a/Transceiver52M/device/ipc/IPCDevice.cpp
+++ b/Transceiver52M/device/ipc/IPCDevice.cpp
@@ -837,6 +837,42 @@ out_close:
return -1;
}
+void IPCDevice::manually_poll_sock_fds() {
+ struct timeval wait = {0, 100000};
+ fd_set crfds, cwfds;
+ int max_fd = 0;
+
+ FD_ZERO(&crfds);
+ FD_ZERO(&cwfds);
+ for(int i = 0; i < chans; i++) {
+ struct osmo_fd* curr_fd = &sk_chan_state[i].conn_bfd;
+ max_fd = curr_fd->fd > max_fd ? curr_fd->fd : max_fd;
+
+ if(curr_fd->when & OSMO_FD_READ)
+ FD_SET(curr_fd->fd, &crfds);
+ if(curr_fd->when & OSMO_FD_WRITE)
+ FD_SET(curr_fd->fd, &cwfds);
+ }
+
+ select(max_fd+1, &crfds, &cwfds, 0, &wait);
+
+ for(int i = 0; i < chans; i++) {
+ int flags = 0;
+ struct osmo_fd* ofd = &sk_chan_state[i].conn_bfd;
+
+ if (FD_ISSET(ofd->fd, &crfds)) {
+ flags |= OSMO_FD_READ;
+ FD_CLR(ofd->fd, &crfds);
+ }
+
+ if (FD_ISSET(ofd->fd, &cwfds)) {
+ flags |= OSMO_FD_WRITE;
+ FD_CLR(ofd->fd, &cwfds);
+ }
+ if(flags)
+ ipc_chan_sock_cb(ofd, flags);
+ }
+}
/* the call stack is rather difficult here, we're already in select:
>~"#0 IPCDevice::start (this=<optimized out>) at IPCDevice.cpp:789\n"
>~"#1 in RadioInterface::start (this=0x614000001640) at radioInterface.cpp:187\n"
@@ -859,6 +895,7 @@ bool IPCDevice::start()
struct msgb *msg;
struct ipc_sk_chan_if *ipc_prim;
+ struct timeval timer_now, timeout;
for(int i = 0; i < chans; i++) {
msg = ipc_msgb_alloc(IPC_IF_MSG_START_REQ);
@@ -870,23 +907,26 @@ bool IPCDevice::start()
ipc_sock_send(&sk_chan_state[i], msg);
}
- int chan_started_count = 0, retrycount = 0;
- while (chan_started_count != chans && retrycount < 5) {
+ gettimeofday(&timeout, 0);
+ timeout.tv_sec += 2;
+
+ int chan_started_count = 0;
+ while (chan_started_count != chans) {
chan_started_count = 0;
/* just poll here, we're already in select, so there is no other way to drive
* the fds and "wait" for a response or retry */
- usleep(100000);
- osmo_select_main(1);
+ manually_poll_sock_fds();
for(unsigned int i = 0; i < ARRAY_SIZE(trx_is_started); i++)
if(trx_is_started[i] == true)
chan_started_count++;
- retrycount++;
+
+ gettimeofday(&timer_now, 0);
+ if(timercmp(&timer_now, &timeout, >))
+ return false;
}
- if(retrycount >= 5)
- return false;
int max_bufs_to_flush = 0;
for(unsigned int i = 0; i < shm_dec->num_chans; i++) {
@@ -903,6 +943,7 @@ bool IPCDevice::stop()
{
struct msgb *msg;
struct ipc_sk_chan_if *ipc_prim;
+ struct timeval timer_now, timeout;
if (!started)
return true;
@@ -915,30 +956,33 @@ bool IPCDevice::stop()
ipc_prim = (struct ipc_sk_chan_if *)msg->data;
ipc_prim->u.start_req.dummy = 0;
-
ipc_sock_send(&sk_chan_state[i], msg);
}
}
- int chan_started_count = 0, retrycount = 0;
+ gettimeofday(&timeout, 0);
+ timeout.tv_sec += 2;
+
+ int chan_started_count = 0;
do {
chan_started_count = 0;
/* just poll here, we're already in select, so there is no other way to drive
* the fds and "wait" for a response or retry */
- usleep(100000);
- osmo_select_main(1);
+ manually_poll_sock_fds();
for(unsigned int i = 0; i < ARRAY_SIZE(trx_is_started); i++)
if(trx_is_started[i] == true)
chan_started_count++;
- retrycount++;
- } while (chan_started_count > 0 && retrycount < 5);
- if(retrycount > 4)
- LOGC(DDEV, ERR) << "No response to stop msg received, terminating anyway...";
- else
- LOGC(DDEV, NOTICE) << "All chanels stopped, termianting...";
+ gettimeofday(&timer_now, 0);
+ if(timercmp(&timer_now, &timeout, >)) {
+ LOGC(DDEV, ERR) << "No response to stop msg received, terminating anyway...";
+ break;
+ }
+ } while (chan_started_count > 0);
+
+ LOGC(DDEV, NOTICE) << "All chanels stopped, terminating...";
/* reset internal buffer timestamps */
for (size_t i = 0; i < rx_buffers.size(); i++)
diff --git a/Transceiver52M/device/ipc/IPCDevice.h b/Transceiver52M/device/ipc/IPCDevice.h
index 592b202..2429eee 100644
--- a/Transceiver52M/device/ipc/IPCDevice.h
+++ b/Transceiver52M/device/ipc/IPCDevice.h
@@ -82,6 +82,7 @@ class IPCDevice : public RadioDevice {
virtual bool flush_recv(size_t num_pkts);
void update_stream_stats_rx(size_t chan, bool *overrun);
void update_stream_stats_tx(size_t chan, bool *underrun);
+ void manually_poll_sock_fds();
public:
virtual void ipc_sock_close(ipc_sock_state *state);