Project

General

Profile

Actions

Support #7323

closed

using BroadCast-example for fast value update

Added by Fabian V over 4 years ago. Updated over 4 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
Start date:
11/13/2019
Due date:
% Done:

0%

Estimated time:

Description

Using Wt-4.1.1, Chrome, ubuntu 18.04

Hi!

I'm using the BroadCast-example to build an application that shows values in different browser-windows. My first test opens 10 browser-windows to show one single value which is updated by a server-post every 20ms. After a while the whole application crashes with a segfault. I'm helpless what the error could be. Am I updating too fast? Which speed of updating is possible?

Here's the run-server-loop:

void Server::run()
{
  for(;;) {
    try {
      std::this_thread::sleep_for(std::chrono::milliseconds(20));
      if(stop_) return;

      {
        std::unique_lock lock(mutex_);
        counter_ = Data::instance().get(); // content_ is a member of Server-class (type double)

        for(auto& c : connections_) {
          Wt::WServer::instance()->post(c.sessionId, c.function);
        }
      }
    }
    catch(...){
      logger->error("unknown error");
    }
  }
}

The Data::instance()-object is a singleton that has locks:

class Data
{
public:
  Data() = default;
  ~Data() = default;

  void set(double value)
  {
    std::unique_lock<std::mutex> lock(mutex_);
    value_ = value;
  }

  double get() const
  {
    std::unique_lock<std::mutex> lock(mutex_);
    return value_;
  }

  static Data& instance()
  {
    static Data _instance;
    return _instance;
  }

private:
  double value_{0};
  mutable std::mutex mutex_;
};

Files

broadcast_example_issue_7323.patch (1.24 KB) broadcast_example_issue_7323.patch Roel Standaert, 11/14/2019 02:41 PM
Actions #1

Updated by Roel Standaert over 4 years ago

While 20ms may be pretty fast (if you're not using WebSockets I would recommend enabling that to lower the overhead), but that should not cause segmentation faults. I can't immediately tell from your code where it's are going wrong.

If you want to find the source of the segfault, I'd recommend running it with gdb and seeing what the backtrace is when the segfault happens. Using valgrind (though this will slow things down a lot) or address sanitizer could also help.

Actions #2

Updated by Fabian V over 4 years ago

Hi thanks for the response!

Actually I don't know how to enable websockets for wt? Is there any example you could recommend?

I've tested my code and it even crashes when I use a local double-variable and d somiething like "content_" (please see code below). So there's no big change comparing to the BroadCast-example.

The program crashes while trying to execute the function pointer "c.function" and it looks like there's going somithing wrong with WObserver. So I thought this might be a wt-internal problem. You should be able to comprehend the problem if you just run the BroadCast-example and set the sleep to <=20ms and inkrement a double member. After a while the program crashes.

Befor using somithing like this example in my company's software, I need to make shure that the Server/Execution doesn't crash in this example program.

void Server::run()
{
  for(;;) {
    try {
      std::this_thread::sleep_for(std::chrono::milliseconds(20));
      if(stop_) return;

      {
        std::unique_lock lock(mutex_);
        if(counter_++ > 10000) counter_ = 0;

        for(auto& c : connections_) {
          Wt::WServer::instance()->post(c.sessionId, c.function);
        }
      }
    }
    catch(...){
      logger->error("unknown error");
    }
  }
}
Actions #3

Updated by Roel Standaert over 4 years ago

You can enable WebSockets in your wt_config.xml.

A simple one that only enables WebSockets would look like this:

<server>
  <application-settings location="*">
    <web-sockets>true</web-sockets>
  </application-settings>
</server>

You can provide a custom config with the -c option if you're using the wthttp connector.

What exactly do you mean by "after a while"? How many sessions do you have going at the same time?

I provided the simple patch I'm testing with, if I understood your description of the issue correctly, and that seems to be working perfectly fine (even when not using WebSockets). I'm using the latest master on Ubuntu 18.04. I'm not using the operating system's Boost, though. I'm using Boost 1.68.0.

Actions #4

Updated by Fabian V over 4 years ago

Ok thanks I'll check that option.

The following command says 1.62 of boost:

cat /usr/include/boost/version.hpp | grep "BOOST_LIB_VERSION"

I'm running the tests in a VM and I'm using chrome. I've opened 10 windows and let them show the website.

The crash sometimes comes after a few minutes and sometimes after 30 minutes. If you set the sleep down to 1 ms the program crashes faster.

Actions #5

Updated by Roel Standaert over 4 years ago

I think I see it (after shortening the timeout and running with address sanitizer).

An observing_ptr is being put into an function object (the bindSafe), and because that function object is being passed to schedule() that causes it at some point to be copied, causing a call to addObserver when we don't have the application lock.

Actions #6

Updated by Roel Standaert over 4 years ago

So, ironically, the safe thing here is to not use bindSafe(...).

Actions #7

Updated by Fabian V over 4 years ago

Ok that sounds funny. So the right way would be just to call the function?

Like this (from BroadCast-example ClientWidget-ctor:

server.connect(this, ([this]() { updateData(); }));
Actions #8

Updated by Roel Standaert over 4 years ago

Yes, a lambda capture of this, or std::bind would work here.

The whole observing\_ptr@/@observable system is not thread safe (on purpose: it's a simpler, more lightweight solution). It is only intended for use when you have the ApplicationLock.

This is indeed an error in that example.

Actions #9

Updated by Fabian V over 4 years ago

Ok, great thanks for the support.

Actions #10

Updated by Roel Standaert over 4 years ago

  • Status changed from Feedback to Resolved

I updated the example.

Actions #11

Updated by Roel Standaert over 4 years ago

  • Status changed from Resolved to Closed
Actions

Also available in: Atom PDF