uspace: avoid use of message queue in main thread

Several tests (including hm2-idrom and module-loading) rely on
capturing output of a halrun session and grepping inside it; this in
turn creates an assumption about how output from rtapi_app (startup
and loadrt-time) and halcmd is interleaved.

With the introduction of the message queue, this assumption was
broken.  Attempt to put back the assumption by bypassing the message
queue when the message is being printed from the "main thread",
i.e., the one that creates the App() object and responds to
load/unload/etc commands.

Comparing pthread_t objects to 0 or to another pthread_t with == is
not portable, but on common platforms it's either an integral type
or a pointer (verified by compile on linux and glance at header on
freebsd, plus
http://stackoverflow.com/questions/30867779/correct-pthread-t-initialization-and-handling
which has to cite something weird like dgux for an exception)

Before this change, tests/module-loading/pid/num_chan=16 failed with
a frequency of between 1-in-100 and 1-in-500 runs on my odroid u3.
After this change, it succeeds for 3000+ iterations without error,
the same as before merging the uspace-plus branch.

Signed-off-by: Jeff Epler <jepler@unpythonic.net>
This commit is contained in:
Jeff Epler 2016-07-29 09:39:56 -05:00
parent 106fcd8a02
commit e996a30f96

View file

@ -421,11 +421,10 @@ static int callback(int fd)
return !force_exit && instance_count > 0; return !force_exit && instance_count > 0;
} }
static pthread_t main_thread{};
static int master(int fd, vector<string> args) { static int master(int fd, vector<string> args) {
if(pthread_create(&queue_thread, nullptr, &queue_function, nullptr) < 0) { main_thread = pthread_self();
perror("pthread_create (queue function)");
return -1;
}
do_load_cmd("hal_lib", vector<string>()); instance_count = 0; do_load_cmd("hal_lib", vector<string>()); instance_count = 0;
App(); // force rtapi_app to be created App(); // force rtapi_app to be created
int result=0; int result=0;
@ -1123,10 +1122,14 @@ long long rtapi_get_time() {
} }
void default_rtapi_msg_handler(msg_level_t level, const char *fmt, va_list ap) { void default_rtapi_msg_handler(msg_level_t level, const char *fmt, va_list ap) {
if(main_thread && pthread_self() != main_thread) {
message_t m; message_t m;
m.level = level; m.level = level;
vsnprintf(m.msg, sizeof(m.msg), fmt, ap); vsnprintf(m.msg, sizeof(m.msg), fmt, ap);
rtapi_msg_queue.push(m); rtapi_msg_queue.push(m);
} else {
vfprintf(level == RTAPI_MSG_ALL ? stdout : stderr, fmt, ap);
}
} }
long int rtapi_delay_max() { return 10000; } long int rtapi_delay_max() { return 10000; }