Project

General

Profile

Actions

Bug #4878

closed

Wt memner usega from handleRequest

Added by Henry Morgan almost 8 years ago. Updated over 7 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
Start date:
04/28/2016
Due date:
% Done:

0%

Estimated time:

Description

Hello

I have a problem with WResource. Once i created new class inherited from WResource and try to use static Wt::WApplication::readConfigurationProperty from handleRequest, it returns empty string always. Same call from different places returns appropriate not empty string. Same situation is with WTimer - it never reaches callback but active. What is it?

Thanks for help

Regards


Files

restest.cpp (2.27 KB) restest.cpp Henry Morgan, 04/28/2016 10:04 PM
Actions #1

Updated by Henry Morgan almost 8 years ago

I've investigated this case in datils. So i found that these things happened only in case when i'm trying to assign static resource to WResource:

...

std::string strSvcHelperResource = "/helper_" + instance()->environment().sessionId();

instance()environment().server()>addResource(&m_oSvcHelper, strSvcHelperResource);

m_oSvcHelper.setResourcePath(strSvcHelperResource);

....

Everything is ok in case of session related resource.

Actions #2

Updated by Wim Dumon almost 8 years ago

  • Status changed from New to Resolved

Call the WServer's readConfigurationProperty method. There is no WApplication object in the context of the call to handleRequest() in general (handleResource is called without grabbing the WApplication lock to which the resource belongs), and in particular not for static resources (since there is no relation at all to any WApplication instance).

You should be able to get the server object by calling WServer::instance() (in case you have only one server, which is usually the case).

Wim.

Actions #3

Updated by Henry Morgan almost 8 years ago

Unfortunately it's not related to readConfigurationProperty and contexts, it was just sympthom. Call of the class's member function Dummy()inheriting WResource has same result:

...

Dummy(); //Causes nothing with class member data

self->Dummy(); //Causes page fault. CDummyClass *self=this;

...

This means that assigning of the static resource to WResource corrupts relation table (class data)<->(functions/inheritance) and only way to use it to work with class data and not with functions.

I use Wt::WApplication::readConfigurationProperty and timer functions from handleRequest without problems as long as local resource is assigned.

Actions #4

Updated by Wim Dumon almost 8 years ago

  • Status changed from Resolved to Feedback

This surely is not as intended. Can you provide a small code example that demonstrates this problem?

Wim.

Actions #5

Updated by Henry Morgan almost 8 years ago

Here you are :)

Actions #6

Updated by Henry Morgan almost 8 years ago

btw you need to open main page and request /test within 10 sec.

Actions #7

Updated by Wim Dumon almost 8 years ago

  • Status changed from Feedback to Resolved

Hey,

I see two weird things in this code.

Note that on one hand you have a WServer, and on the other hand you have a WApplication. Your WServer object stays alive during the time that your server is accessible, while a WApplication object is created when a session is started, and destroyed when a session terminates (either through timeout, explicit notification from the client, or by caling quit() on the WApplication object).

A static resource represents what has to happen when a global, static URL is accessed. Static resources configured on the WServer. During the lifetime of the WServer object, any request to the URL that it is bound to, will be handled by that resource. Therefore, we typically see static resources added in the same area where you call server.addEntryPoint(). By calling server.addResource() in each application constructor, as in your code example, you're re-configuring this static URL whenever an application is created, which is not correct. Session related resources do exist in Wt: these are the WResources that are not bound to a static URL. They will have a random URL, ensuring that they are only known to the browsers of the active session, and the URL is only valid as long as the WResource exist. Since the WResource will be deleted when the session is terminated, the URL becomes invalid when the session terminates.

By embedding the WResource as member in your WApplication object, and then registering it to WServer as handler for a static resource, you create a dangling pointer: session is created -> WResource is created and registered. You change the url in your browser -> browser notifies Wt that user goes away, Wt destroys the WApplication object which causes deletion of the WResource, browser accesses URL which is handled by a WResource that is deleted -> page fault.

Static resources must have a lifetime that lasts as long as they are accessible, this is typically the lifetime of your WServer object. So you could e.g. instantiate them in your main() function.

A second problem is the use of WTimer in the static resource. WTimer is a timer that runs in the browser of a user, and that will use JavaScript to initiate an event back to the server after a particular time. WTimer can thus not be used in a static resource, since there is no browser into play. If you want to user server-side timers, you will have to post them in the server's event loop. Get the ioservices related to the server, and schedule an event on the WIOService.

Wim.

Actions #8

Updated by Koen Deforche over 7 years ago

  • Status changed from Resolved to Closed
  • Target version set to 3.3.6
Actions

Also available in: Atom PDF