| 1494 | | </indexterm>. We have removed the Win32-specific threads |
|---|
| 1495 | | because NSPR already supports that implementation. Further |
|---|
| 1496 | | implementations may be removed in favor of using what NSPR |
|---|
| 1497 | | offers. Doing this will offload much of our efforts onto the |
|---|
| 1498 | | NSPR. NSPR threads do not support all the features we have, |
|---|
| 1499 | | however, because they took the lowest-common-denominator |
|---|
| 1500 | | approach. As with all technology, there is a trade-off in |
|---|
| 1501 | | relieving some of our work load by using an existing |
|---|
| 1502 | | cross-platform thread implementation: our interface becomes |
|---|
| 1503 | | limited to what features that implementation provides. It |
|---|
| 1504 | | remains to be seen exactly how much of VPR's threading |
|---|
| 1505 | | subsystem will be removed, and those programmers who choose |
|---|
| 1506 | | to use it should be careful to watch the mailing lists for |
|---|
| 1507 | | discussions and announcements about changes.</para> |
|---|
| | 1496 | </indexterm>. NSPR threads do not support all the |
|---|
| | 1497 | features we have, however, because they took the |
|---|
| | 1498 | lowest-common-denominator approach. As with all technology, |
|---|
| | 1499 | there is a trade-off in relieving some of our work load by |
|---|
| | 1500 | using an existing cross-platform thread implementation: our |
|---|
| | 1501 | interface becomes limited to what features that |
|---|
| | 1502 | implementation provides. It remains to be seen exactly how |
|---|
| | 1503 | much of VPR's threading subsystem will be removed, and those |
|---|
| | 1504 | programmers who choose to use it should be careful to watch |
|---|
| | 1505 | the mailing lists for discussions and announcements about |
|---|
| | 1506 | changes.</para> |
|---|
| 3254 | | <xref linkend="ref.design.patterns" />. In VPR, the class |
|---|
| | 3253 | <xref linkend="ref.design.patterns" />. VPR offers two ways to |
|---|
| | 3254 | implement a singleton, both of which come from the header |
|---|
| | 3255 | <filename>vpr/Util/Singleton.h</filename>. Libraries such as <ulink |
|---|
| | 3256 | url="http://sourceforge.net/projects/loki-lib/">Loki</ulink> offer |
|---|
| | 3257 | other approaches.</para> |
|---|
| | 3258 | |
|---|
| | 3259 | <para>The first way of creating a singleton using VPR is to use the C |
|---|
| | 3260 | preprocessor approach. In this case, we utilize two macros: |
|---|
| | 3261 | <literal>vprSingletonHeader()</literal><indexterm> |
|---|
| | 3262 | <primary>macros</primary> |
|---|
| | 3263 | |
|---|
| | 3264 | <secondary>vprSingletonHeader</secondary> |
|---|
| | 3265 | </indexterm> and <literal>vprSingletonImp()</literal><indexterm> |
|---|
| | 3266 | <primary>macros</primary> |
|---|
| | 3267 | |
|---|
| | 3268 | <secondary>vprSingletonImp</secondary> |
|---|
| | 3269 | </indexterm>. One goes in the class declaration (in the header |
|---|
| | 3270 | file), and the other goes with the class definition (in the |
|---|
| | 3271 | <filename>.cpp</filename> file). The basic usage of these macros is |
|---|
| | 3272 | shown in <xref linkend="example.vprSingletonHeader" /> and <xref |
|---|
| | 3273 | linkend="example.vprSingletonImp" />.</para> |
|---|
| | 3274 | |
|---|
| | 3275 | <example id="example.vprSingletonHeader"> |
|---|
| | 3276 | <title>Use of <literal>vprSingletonHeader()</literal></title> |
|---|
| | 3277 | |
|---|
| | 3278 | <programlisting>#include <boost/noncopyable.hpp> |
|---|
| | 3279 | #include <vpr/Util/Singleton.h> |
|---|
| | 3280 | |
|---|
| | 3281 | class MySingleton : boost::noncopyable |
|---|
| | 3282 | { |
|---|
| | 3283 | public: |
|---|
| | 3284 | // Public operations ... |
|---|
| | 3285 | void doSomething(); |
|---|
| | 3286 | |
|---|
| | 3287 | private: |
|---|
| | 3288 | // Prevent instantiation by user code. |
|---|
| | 3289 | MySingleton() |
|---|
| | 3290 | { |
|---|
| | 3291 | // Some constructor actions ... |
|---|
| | 3292 | } |
|---|
| | 3293 | |
|---|
| | 3294 | // Bring in the singleton declaration pieces. |
|---|
| | 3295 | vprSingletonHeader(MySingleton); |
|---|
| | 3296 | };</programlisting> |
|---|
| | 3297 | </example> |
|---|
| | 3298 | |
|---|
| | 3299 | <example id="example.vprSingletonImp"> |
|---|
| | 3300 | <title>Use of <literal>vprSingletonImp()</literal></title> |
|---|
| | 3301 | |
|---|
| | 3302 | <programlisting>#include "MySingleton.h" |
|---|
| | 3303 | |
|---|
| | 3304 | // Bring in the singleton definition pieces. |
|---|
| | 3305 | vprSingletonImp(MySingleton); |
|---|
| | 3306 | |
|---|
| | 3307 | void MySingleton::doSomething() |
|---|
| | 3308 | { |
|---|
| | 3309 | // Do something ... |
|---|
| | 3310 | }</programlisting> |
|---|
| | 3311 | </example> |
|---|
| | 3312 | |
|---|
| | 3313 | <para>In some cases, an object may need to perform some |
|---|
| | 3314 | initialization steps after being instantiated. In that case, use the |
|---|
| | 3315 | macro <literal>vprSingletonHeaderWithInitFunc()</literal><indexterm> |
|---|
| | 3316 | <primary>macros</primary> |
|---|
| | 3317 | |
|---|
| | 3318 | <secondary>vprSingletonHeaderWithInitFunc</secondary> |
|---|
| | 3319 | </indexterm> instead of <literal>vprSingletonHeader()</literal> |
|---|
| | 3320 | and <literal>vprSingletonImpWithInitFunc()</literal><indexterm> |
|---|
| | 3321 | <primary>macros</primary> |
|---|
| | 3322 | |
|---|
| | 3323 | <secondary>vprSingletonImpWithInitFunc</secondary> |
|---|
| | 3324 | </indexterm> instead of <literal>vprSingletonImp()</literal>. An |
|---|
| | 3325 | example of this is shown in <xref |
|---|
| | 3326 | linkend="example.vprSingletonHeaderWithInitFunc" /> and <xref |
|---|
| | 3327 | linkend="example.vprSingletonImpWithInitFunc" />. The initialization |
|---|
| | 3328 | method must take no parameters and return nothing.</para> |
|---|
| | 3329 | |
|---|
| | 3330 | <example id="example.vprSingletonHeaderWithInitFunc"> |
|---|
| | 3331 | <title>Use of |
|---|
| | 3332 | <literal>vprSingletonHeaderWithInitFunc()</literal></title> |
|---|
| | 3333 | |
|---|
| | 3334 | <programlisting>#include <boost/noncopyable.hpp> |
|---|
| | 3335 | #include <vpr/Util/Singleton.h> |
|---|
| | 3336 | |
|---|
| | 3337 | class MySingleton : boost::noncopyable |
|---|
| | 3338 | { |
|---|
| | 3339 | public: |
|---|
| | 3340 | // Public operations ... |
|---|
| | 3341 | void doSomething(); |
|---|
| | 3342 | |
|---|
| | 3343 | private: |
|---|
| | 3344 | // Prevent instantiation by user code. |
|---|
| | 3345 | MySingleton() |
|---|
| | 3346 | { |
|---|
| | 3347 | // Some constructor actions ... |
|---|
| | 3348 | } |
|---|
| | 3349 | |
|---|
| | 3350 | void init() |
|---|
| | 3351 | { |
|---|
| | 3352 | // Perform initialization operations ... |
|---|
| | 3353 | } |
|---|
| | 3354 | |
|---|
| | 3355 | // Bring in the singleton declaration pieces. |
|---|
| | 3356 | vprSingletonHeaderWithInitFunc(MySingleton, init); |
|---|
| | 3357 | };</programlisting> |
|---|
| | 3358 | </example> |
|---|
| | 3359 | |
|---|
| | 3360 | <example id="example.vprSingletonImpWithInitFunc"> |
|---|
| | 3361 | <title>Use of |
|---|
| | 3362 | <literal>vprSingletonImpWithInitFunc()</literal></title> |
|---|
| | 3363 | |
|---|
| | 3364 | <programlisting>#include "MySingleton.h" |
|---|
| | 3365 | |
|---|
| | 3366 | // Bring in the singleton definition pieces. |
|---|
| | 3367 | vprSingletonImp(MySingleton); |
|---|
| | 3368 | |
|---|
| | 3369 | void MySingleton::doSomething() |
|---|
| | 3370 | { |
|---|
| | 3371 | // Do something ... |
|---|
| | 3372 | }</programlisting> |
|---|
| | 3373 | </example> |
|---|
| | 3374 | |
|---|
| | 3375 | <para>In VPR 1.1 and beyond, the destructor for singleton objects is |
|---|
| | 3376 | called when the application exits. This can result in some |
|---|
| | 3377 | undesirable behavior if one singleton depends on another, thus |
|---|
| | 3378 | meaning that the order in which they are deleted can make a |
|---|
| | 3379 | difference. Without any specific ordering being imposed, singleton |
|---|
| | 3380 | objects are deleted in the reverse order in which they were |
|---|
| | 3381 | instantiated. Since it is not always possible to control the order of |
|---|
| | 3382 | instantiation, it can be useful to control the order of destruction. |
|---|
| | 3383 | This can be done by setting the <quote>lifetime</quote> or |
|---|
| | 3384 | <quote>longevity</quote> of a singleton. The higher the longevity, |
|---|
| | 3385 | the later that the singleton will be deleted when the application is |
|---|
| | 3386 | exiting. This is accomplished using either |
|---|
| | 3387 | <literal>vprSingletonImpLifetime()</literal><indexterm> |
|---|
| | 3388 | <primary>macros</primary> |
|---|
| | 3389 | |
|---|
| | 3390 | <secondary>vprSingletonImpLifetime</secondary> |
|---|
| | 3391 | </indexterm> or |
|---|
| | 3392 | <literal>vprSingletonImpLifetimeWithInitFunc()</literal><indexterm> |
|---|
| | 3393 | <primary>macros</primary> |
|---|
| | 3394 | |
|---|
| | 3395 | <secondary>vprSingletonImpLifetimeWithInitFunc</secondary> |
|---|
| | 3396 | </indexterm>. The macro used must be paired with either |
|---|
| | 3397 | <literal>vprSingletonHeader()</literal> or |
|---|
| | 3398 | <literal>vprSingletonHeaderWithInitFunc()</literal>. Usage of |
|---|
| | 3399 | <literal>vprSingletonImpLifetime()</literal> is shown in <xref |
|---|
| | 3400 | linkend="example.vprSingletonImpLifetime" />.</para> |
|---|
| | 3401 | |
|---|
| | 3402 | <example id="example.vprSingletonImpLifetime"> |
|---|
| | 3403 | <title>Use of <literal>vprSingletonImpLifetime()</literal></title> |
|---|
| | 3404 | |
|---|
| | 3405 | <programlisting>#include "MySingleton.h" |
|---|
| | 3406 | |
|---|
| | 3407 | // Bring in the singleton definition pieces. Delete it early |
|---|
| | 3408 | // in the application exit process. |
|---|
| | 3409 | vprSingletonImpLifetime(MySingleton, 10); |
|---|
| | 3410 | |
|---|
| | 3411 | void MySingleton::doSomething() |
|---|
| | 3412 | { |
|---|
| | 3413 | // Do something ... |
|---|
| | 3414 | }</programlisting> |
|---|
| | 3415 | </example> |
|---|
| | 3416 | |
|---|
| | 3417 | <para>The other approach uses a template class called |
|---|