Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What's the most RIOT-like way for a shell command to quit on ^C without wasting a thread to block on reading stdin? #10715

Closed
benemorius opened this issue Jan 6, 2019 · 2 comments
Assignees
Labels
State: stale State: The issue / PR has no activity for >185 days Type: question The issue poses a question regarding usage of RIOT

Comments

@benemorius
Copy link
Member

I'm implementing a telnet server and a kernel message ring buffer (#7446) with a shell command like dmesg to read and clear it. I want to add dmesg -w (works like tail -f) which mustn't return until the user interrupts it.

I'm not sure of the best way to do this without dedicating a thread to block on reading stdin.

I don't think we can fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) but even if we could we'd then be polling and that's not ideal either.

I think it would be appropriate to use select() to have a single thread block simultaneously on both stdin and the file that produces dmesg output (via vfs_bind()), but I don't think select() and friends are implemented either.

The main thread will normally be blocked (via getc() or something else) waiting for new kernel messages to be printed. The goal is to allow the user to interrupt this with ^C to get a prompt back, and to do it in a resource-friendly way.

@benemorius benemorius changed the title What's the most RIOT-like way for a shell command to quit on ^C without wasting a thread to block on stdin? What's the most RIOT-like way for a shell command to quit on ^C without wasting a thread to block on reading stdin? Jan 6, 2019
@jcarrano jcarrano added the Type: question The issue poses a question regarding usage of RIOT label Jan 7, 2019
@jcarrano
Copy link
Contributor

jcarrano commented Mar 4, 2019

@benemorius

First let me begin by noting that your question is very valid. The behaviour you described, however it is implemented, should be possible to achieve without an additional thread. The fact that it is not (at least not easily) means that there is something wrong that we need to fix.

To answer to your comment in #11004 .

I didn't test this yet but it sounds like you're thinking this should terminate a running process with ^C (that's what #10715 is about) which would be lovely too

There's no "easy" way of doing that. Aside from RIOT specifics, which may make the task harder (or easier) the main obstacle with that is that there are no "processes" in RIOT, only threads. AFAIK this is also true of the other major embedded OSes that target this class of devices. Now, which thread gets killed on CTRL-C? Clearly not the "running" thread (any thread could be running at that instant). In a UNIX terminal, the foreground process is terminated (not really, see next point) but there is no "foreground thread" in RIOT. Finally, tasks should not be killed by ctrl-c, there has to be some graceful termination/cleanup, etc.

The last point is where we have more trouble now, as you well mention in your post. The function/thread that implements the command must wait for at least two different types of events: the one it needs in order to achieve its purpose and the "termination" event. It could also be implemented in the IO layer component that implements the message buffer pseudo-file (an interrupted read could return EINTR).

How are you implementing the message pseudo-file? If it is done with a message queue, it is a matter of sending another message on ctrl-c to the same queue. If it is implemented with a raw circular buffer protected by locks, then the locks could be made interruptible.

@stale
Copy link

stale bot commented Sep 5, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions.

@stale stale bot added the State: stale State: The issue / PR has no activity for >185 days label Sep 5, 2019
@stale stale bot closed this as completed Oct 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
State: stale State: The issue / PR has no activity for >185 days Type: question The issue poses a question regarding usage of RIOT
Projects
None yet
Development

No branches or pull requests

3 participants