03.01.2013 Views

Chapter 1

Chapter 1

Chapter 1

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

� The original program consisted of a sequential engine, with perhaps a second thread<br />

being used for interface work. In that case, it is generally more efficient not to create a<br />

CPosixServer and to use STDLIB in 'direct' mode. Indeed, if you introduce several,<br />

separate engines into a program – CODECs for different sound formats, for example –<br />

then you still need not use a CPosixServer object, as the various engines won't be<br />

sharing files.<br />

� If the original engine was designed in a multithreaded manner, then you will almost<br />

certainly have to use a CPosixServer. Remember, though, that you can only share<br />

STDLIB objects, so you're totally dependent on the functionality it provides you.<br />

The background active object processing technique is more memory- efficient, more<br />

predictable, and almost always preferred – assuming you have the choice.<br />

8.2.3 Global Data<br />

As was mentioned earlier, writable global data is not allowed in Symbian OS DLLs. This can<br />

cause problems for ported code. In practice, there are several approaches for dealing with<br />

this, but they involve some rewriting:<br />

� Thread local storage (TLS)<br />

� Explicit This<br />

� Global variables masterclass<br />

Thread local storage<br />

Thread Local Storage is the closest thing there is to global variables in Symbian OS. For<br />

each DLL, it is possible to register a pointer to a dynamically created struct or class<br />

object, and then to look it up whenever it is required. The basis of the technique is that<br />

having done this, all global variables are remapped to data fields within the structure. In fact,<br />

this is on a per thread, per DLL basis, with each thread potentially having its own globals.<br />

(Indeed, this is how the STDLIB implements errno and other global variables so that each<br />

thread has its own errno copy.) If you use multithreading, you will have to be careful about<br />

this.<br />

The generally recommended way of using TLS is to incorporate OpenL() and Close()<br />

functions, and then to call these as the program is created or shut down – typically from the<br />

document or app UI classes' constructors and destructors. The OpenL() and Close()<br />

functions are then responsible for creating and destroying the global object respectively. A<br />

possible implementation is as follows (where Globals is the struct that holds the global<br />

data).<br />

EXPORT_C void MyEngine::OpenL()<br />

{<br />

Globals *globals = STATIC_CAST(Globals*, Dll::Tls());<br />

if(globals == NULL)<br />

{<br />

globals = new(ELeave) Globals;<br />

Mem::FillZ(globals, sizeof(Globals));<br />

Dll::SetTls(globals);<br />

}<br />

globals->_count += 1;<br />

}

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!