Project

General

Profile

Bug #8305 » test_wrasterimage_gm_race_20210401a.C

Bruce Toll, 04/05/2021 03:15 PM

 
#include <Wt/WApplication.h>
#include <Wt/WBrush.h>
#include <Wt/WColor.h>
#include <Wt/WContainerWidget.h>
#include <Wt/WEnvironment.h>
#include <Wt/WImage.h>
#include <Wt/WPainter.h>
#include <Wt/WPen.h>
#include <Wt/WRasterImage.h>
#include <Wt/WRectF.h>
#include <Wt/WTable.h>

using namespace Wt;

static constexpr int TABLE_ROWS = 16;
static constexpr int TABLE_COLS = 40;
static constexpr int ARC_BOX_SIDE_LEN = 40;

class ImageResource;

class PaintedImage : public WImage
{
public:
PaintedImage(int arc_box_side_len, double span_angle);
~PaintedImage() { }

private:
double span_angle_;
std::shared_ptr<ImageResource> resource_;

friend ImageResource;
};

class ImageResource : public WResource
{
public:
ImageResource(PaintedImage *img)
: WResource(),
img_(img)
{ }

virtual ~ImageResource()
{
beingDeleted();
}

virtual void handleRequest(const Http::Request& request,
Http::Response& response) {
WRasterImage device("png", img_->width(), img_->height());
paint(&device, img_);

device.handleRequest(request, response);
}

void paint(WPaintDevice *paintDevice, PaintedImage *img)
{
WPainter p(paintDevice);
p.save();
p.setBrush(WBrush(StandardColor::Blue));
p.setPen(WPen(PenStyle::None));
auto rect = WRectF(0.0, 0.0, img_->width().toPixels(), img_->height().toPixels());
p.drawArc(rect, img_->span_angle_ * 16, 180 * 16);
p.setBrush(WBrush(StandardColor::Yellow));
p.drawArc(rect, img_->span_angle_ * 16 + 180 * 16, (360 - 180) * 16);
p.restore();
}

private:
PaintedImage *img_;
};

PaintedImage::PaintedImage(int arc_box_side_len, double span_angle) :
Wt::WImage(), span_angle_(span_angle)
{
resize(arc_box_side_len, arc_box_side_len);
resource_ = std::make_shared<ImageResource>(this);
setImageLink(WLink(resource_));
}

class TestApp : public WApplication {
public:
TestApp(const WEnvironment& env);
};

TestApp::TestApp(const WEnvironment& env) : WApplication(env)
{
setTitle("Test WRasterImage-gm race condition");

auto table = root()->addNew<WTable>();
for (int r = 0; r < TABLE_ROWS; ++r) {
for (int c = 0; c < TABLE_COLS; ++c) {
double span_angle = 360.0 * ((double) r / TABLE_ROWS + (double) c / TABLE_ROWS / TABLE_COLS);
table->elementAt(r, c)->addNew<PaintedImage>(ARC_BOX_SIDE_LEN, span_angle);
}
}
}

int main(int argc, char **argv)
{
return WRun(argc, argv, [&](const WEnvironment& env) {return std::make_unique<TestApp>(env);});
}
(1-1/2)