source: sources/src/exceptionBasic.cc @ 1466:1d08fcd3c7e0

Revision 1466:1d08fcd3c7e0, 27.5 KB checked in by niam, 22 months ago (diff)

[exception] use singleton only in case of DL

Line 
1/***************************************************************************
2 *            exceptionBasic.cc
3 *
4 *  Sun Jul 17 2005
5 *  Copyright  2005  Dmytro Milinevskyy
6 *  milinevskyy@gmail.com
7 ****************************************************************************/
8
9/*
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU Lesser General Public License version 2.1 as published by
12 *  the Free Software Foundation;
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Lesser General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24/**
25 * vim indentation settings
26 * set tabstop=4
27 * set shiftwidth=4
28 */
29
30#include <libdodo/directives.h>
31
32#ifdef DL_EXT
33#include <dlfcn.h>
34#include <string.h>
35#endif
36#ifdef __GNUC__
37#include <cxxabi.h>
38#endif
39#ifdef PTHREAD_EXT
40#include <pthread.h>
41#endif
42#include <stdlib.h>
43#include <stdio.h>
44
45#include <libdodo/exceptionBasic.h>
46
47#define CALLSTACK_MAXLEN 64
48
49using namespace dodo::exception;
50
51__thread __context__ dodo::exception::global_exeption_context = {
52    NULL,
53    NULL};
54
55__thread char dodo::exception::exeption_storage[sizeof(basic)];
56
57#ifdef DL_EXT
58unsigned long basic::instances = 0;
59#endif
60
61//-------------------------------------------------------------------
62
63bool basic::handlerMap[] = {
64    false,
65    false,
66    false,
67    false,
68    false,
69    false,
70    false,
71    false,
72    false,
73    false,
74    false,
75    false,
76    false,
77    false,
78    false,
79    false,
80    false,
81    false,
82    false,
83    false,
84    false,
85    false,
86    false,
87    false,
88    false,
89    false,
90    false,
91    false,
92    false,
93    false,
94    false,
95    false,
96    false,
97    false,
98    false,
99    false,
100    false,
101    false,
102    false,
103    false,
104    false,
105    false,
106    false,
107    false,
108    false,
109    false
110};
111
112//-------------------------------------------------------------------
113
114basic::handler basic::handlers[] = {
115    NULL,
116    NULL,
117    NULL,
118    NULL,
119    NULL,
120    NULL,
121    NULL,
122    NULL,
123    NULL,
124    NULL,
125    NULL,
126    NULL,
127    NULL,
128    NULL,
129    NULL,
130    NULL,
131    NULL,
132    NULL,
133    NULL,
134    NULL,
135    NULL,
136    NULL,
137    NULL,
138    NULL,
139    NULL,
140    NULL,
141    NULL,
142    NULL,
143    NULL,
144    NULL,
145    NULL,
146    NULL,
147    NULL,
148    NULL,
149    NULL,
150    NULL,
151    NULL,
152    NULL,
153    NULL,
154    NULL,
155    NULL,
156    NULL,
157    NULL,
158    NULL,
159    NULL,
160    NULL
161};
162
163//-------------------------------------------------------------------
164
165void *basic::handlerData[] = {
166    NULL,
167    NULL,
168    NULL,
169    NULL,
170    NULL,
171    NULL,
172    NULL,
173    NULL,
174    NULL,
175    NULL,
176    NULL,
177    NULL,
178    NULL,
179    NULL,
180    NULL,
181    NULL,
182    NULL,
183    NULL,
184    NULL,
185    NULL,
186    NULL,
187    NULL,
188    NULL,
189    NULL,
190    NULL,
191    NULL,
192    NULL,
193    NULL,
194    NULL,
195    NULL,
196    NULL,
197    NULL,
198    NULL,
199    NULL,
200    NULL,
201    NULL,
202    NULL,
203    NULL,
204    NULL,
205    NULL,
206    NULL,
207    NULL,
208    NULL,
209    NULL,
210    NULL,
211    NULL
212};
213
214//-------------------------------------------------------------------
215
216#ifdef DL_EXT
217bool basic::handlesOpened[] = {
218    false,
219    false,
220    false,
221    false,
222    false,
223    false,
224    false,
225    false,
226    false,
227    false,
228    false,
229    false,
230    false,
231    false,
232    false,
233    false,
234    false,
235    false,
236    false,
237    false,
238    false,
239    false,
240    false,
241    false,
242    false,
243    false,
244    false,
245    false,
246    false,
247    false,
248    false,
249    false,
250    false,
251    false,
252    false,
253    false,
254    false,
255    false,
256    false,
257    false,
258    false,
259    false,
260    false,
261    false,
262    false
263};
264
265//-------------------------------------------------------------------
266
267void *basic::handles[] = {
268    NULL,
269    NULL,
270    NULL,
271    NULL,
272    NULL,
273    NULL,
274    NULL,
275    NULL,
276    NULL,
277    NULL,
278    NULL,
279    NULL,
280    NULL,
281    NULL,
282    NULL,
283    NULL,
284    NULL,
285    NULL,
286    NULL,
287    NULL,
288    NULL,
289    NULL,
290    NULL,
291    NULL,
292    NULL,
293    NULL,
294    NULL,
295    NULL,
296    NULL,
297    NULL,
298    NULL,
299    NULL,
300    NULL,
301    NULL,
302    NULL,
303    NULL,
304    NULL,
305    NULL,
306    NULL,
307    NULL,
308    NULL,
309    NULL,
310    NULL,
311    NULL,
312    NULL,
313    NULL
314};
315
316//-------------------------------------------------------------------
317
318char basic::cookies[][32] = {
319    {'\0', },
320    {'\0', },
321    {'\0', },
322    {'\0', },
323    {'\0', },
324    {'\0', },
325    {'\0', },
326    {'\0', },
327    {'\0', },
328    {'\0', },
329    {'\0', },
330    {'\0', },
331    {'\0', },
332    {'\0', },
333    {'\0', },
334    {'\0', },
335    {'\0', },
336    {'\0', },
337    {'\0', },
338    {'\0', },
339    {'\0', },
340    {'\0', },
341    {'\0', },
342    {'\0', },
343    {'\0', },
344    {'\0', },
345    {'\0', },
346    {'\0', },
347    {'\0', },
348    {'\0', },
349    {'\0', },
350    {'\0', },
351    {'\0', },
352    {'\0', },
353    {'\0', },
354    {'\0', },
355    {'\0', },
356    {'\0', },
357    {'\0', },
358    {'\0', },
359    {'\0', },
360    {'\0', },
361    {'\0', },
362    {'\0', },
363    {'\0', },
364    {'\0', },
365    {'\0', },
366    {'\0', },
367    {'\0', }
368};
369#endif
370
371//-------------------------------------------------------------------
372
373basic::sync::stack::stack()
374{
375#ifdef PTHREAD_EXT
376    static pthread_mutex_t mutex;
377    static unsigned char mutex_init = 0;
378    if (!mutex_init) {
379        pthread_mutexattr_t attr;
380        pthread_mutexattr_init(&attr);
381        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
382
383        pthread_mutex_init(&mutex, &attr);
384
385        pthread_mutexattr_destroy(&attr);
386
387        mutex_init = 1;
388    }
389
390    keeper = &mutex;
391
392    pthread_mutex_lock((pthread_mutex_t *)keeper);
393#endif
394}
395
396//-------------------------------------------------------------------
397
398basic::sync::stack::~stack()
399{
400#ifdef PTHREAD_EXT
401    pthread_mutex_unlock((pthread_mutex_t *)keeper);
402#endif
403}
404
405//-------------------------------------------------------------------
406
407#ifdef DL_EXT
408basic::basic()
409{
410    instances = 1;
411}
412#endif
413
414//-------------------------------------------------------------------
415
416basic::basic(int              a_module,
417             int              functionID,
418             int              errnoSource,
419             int              a_errno,
420             const dodo::string &a_errstr,
421             unsigned long    a_line,
422             const dodo::string &a_file,
423             const dodo::string &a_message) : source(a_module),
424                                                     function(functionID),
425                                                     errnoSource(errnoSource),
426                                                     errNo(a_errno),
427                                                     errStr(a_errstr),
428                                                     line(a_line),
429                                                     file(a_file),
430                                                     message(a_message)
431{
432    sync::stack tg;
433
434#ifdef __GNUC__
435    using namespace abi;
436
437    __call__ call;
438
439#ifdef DL_EXT
440    Dl_info dlinfo;
441    const char *symname;
442    char *demangled;
443    int status;
444#endif
445
446    for (int i = 0; i < CALLSTACK_MAXLEN; ++i) {
447        switch (i) {
448            case 0:
449                call.address = (void *)((unsigned long)__builtin_return_address(0)&0xFFFFFF00);
450                if (!call.address)
451                    goto handle;
452                break;
453            case 1:
454                call.address = (void *)((unsigned long)__builtin_return_address(1)&0xFFFFFF00);
455                if (!call.address)
456                    goto handle;
457                break;
458            case 2:
459                call.address = (void *)((unsigned long)__builtin_return_address(2)&0xFFFFFF00);
460                if (!call.address)
461                    goto handle;
462                break;
463            case 3:
464                call.address = (void *)((unsigned long)__builtin_return_address(3)&0xFFFFFF00);
465                if (!call.address)
466                    goto handle;
467                break;
468            case 4:
469                call.address = (void *)((unsigned long)__builtin_return_address(4)&0xFFFFFF00);
470                if (!call.address)
471                    goto handle;
472                break;
473            case 5:
474                call.address = (void *)((unsigned long)__builtin_return_address(5)&0xFFFFFF00);
475                if (!call.address)
476                    goto handle;
477                break;
478            case 6:
479                call.address = (void *)((unsigned long)__builtin_return_address(6)&0xFFFFFF00);
480                if (!call.address)
481                    goto handle;
482                break;
483            case 7:
484                call.address = (void *)((unsigned long)__builtin_return_address(7)&0xFFFFFF00);
485                if (!call.address)
486                    goto handle;
487                break;
488            case 8:
489                call.address = (void *)((unsigned long)__builtin_return_address(8)&0xFFFFFF00);
490                if (!call.address)
491                    goto handle;
492                break;
493            case 9:
494                call.address = (void *)((unsigned long)__builtin_return_address(9)&0xFFFFFF00);
495                if (!call.address)
496                    goto handle;
497                break;
498            case 10:
499                call.address = (void *)((unsigned long)__builtin_return_address(10)&0xFFFFFF00);
500                if (!call.address)
501                    goto handle;
502                break;
503            case 11:
504                call.address = (void *)((unsigned long)__builtin_return_address(11)&0xFFFFFF00);
505                if (!call.address)
506                    goto handle;
507                break;
508            case 12:
509                call.address = (void *)((unsigned long)__builtin_return_address(12)&0xFFFFFF00);
510                if (!call.address)
511                    goto handle;
512                break;
513            case 13:
514                call.address = (void *)((unsigned long)__builtin_return_address(13)&0xFFFFFF00);
515                if (!call.address)
516                    goto handle;
517                break;
518            case 14:
519                call.address = (void *)((unsigned long)__builtin_return_address(14)&0xFFFFFF00);
520                if (!call.address)
521                    goto handle;
522                break;
523            case 15:
524                call.address = (void *)((unsigned long)__builtin_return_address(15)&0xFFFFFF00);
525                if (!call.address)
526                    goto handle;
527                break;
528            case 16:
529                call.address = (void *)((unsigned long)__builtin_return_address(16)&0xFFFFFF00);
530                if (!call.address)
531                    goto handle;
532                break;
533            case 17:
534                call.address = (void *)((unsigned long)__builtin_return_address(17)&0xFFFFFF00);
535                if (!call.address)
536                    goto handle;
537                break;
538            case 18:
539                call.address = (void *)((unsigned long)__builtin_return_address(18)&0xFFFFFF00);
540                if (!call.address)
541                    goto handle;
542                break;
543            case 19:
544                call.address = (void *)((unsigned long)__builtin_return_address(19)&0xFFFFFF00);
545                if (!call.address)
546                    goto handle;
547                break;
548            case 20:
549                call.address = (void *)((unsigned long)__builtin_return_address(20)&0xFFFFFF00);
550                if (!call.address)
551                    goto handle;
552                break;
553            case 21:
554                call.address = (void *)((unsigned long)__builtin_return_address(21)&0xFFFFFF00);
555                if (!call.address)
556                    goto handle;
557                break;
558            case 22:
559                call.address = (void *)((unsigned long)__builtin_return_address(22)&0xFFFFFF00);
560                if (!call.address)
561                    goto handle;
562                break;
563            case 23:
564                call.address = (void *)((unsigned long)__builtin_return_address(23)&0xFFFFFF00);
565                if (!call.address)
566                    goto handle;
567                break;
568            case 24:
569                call.address = (void *)((unsigned long)__builtin_return_address(24)&0xFFFFFF00);
570                if (!call.address)
571                    goto handle;
572                break;
573            case 25:
574                call.address = (void *)((unsigned long)__builtin_return_address(25)&0xFFFFFF00);
575                if (!call.address)
576                    goto handle;
577                break;
578            case 26:
579                call.address = (void *)((unsigned long)__builtin_return_address(26)&0xFFFFFF00);
580                if (!call.address)
581                    goto handle;
582                break;
583            case 27:
584                call.address = (void *)((unsigned long)__builtin_return_address(27)&0xFFFFFF00);
585                if (!call.address)
586                    goto handle;
587                break;
588            case 28:
589                call.address = (void *)((unsigned long)__builtin_return_address(28)&0xFFFFFF00);
590                if (!call.address)
591                    goto handle;
592                break;
593            case 29:
594                call.address = (void *)((unsigned long)__builtin_return_address(29)&0xFFFFFF00);
595                if (!call.address)
596                    goto handle;
597                break;
598            case 30:
599                call.address = (void *)((unsigned long)__builtin_return_address(30)&0xFFFFFF00);
600                if (!call.address)
601                    goto handle;
602                break;
603            case 31:
604                call.address = (void *)((unsigned long)__builtin_return_address(31)&0xFFFFFF00);
605                if (!call.address)
606                    goto handle;
607                break;
608            case 32:
609                call.address = (void *)((unsigned long)__builtin_return_address(32)&0xFFFFFF00);
610                if (!call.address)
611                    goto handle;
612                break;
613            case 33:
614                call.address = (void *)((unsigned long)__builtin_return_address(33)&0xFFFFFF00);
615                if (!call.address)
616                    goto handle;
617                break;
618            case 34:
619                call.address = (void *)((unsigned long)__builtin_return_address(34)&0xFFFFFF00);
620                if (!call.address)
621                    goto handle;
622                break;
623            case 35:
624                call.address = (void *)((unsigned long)__builtin_return_address(35)&0xFFFFFF00);
625                if (!call.address)
626                    goto handle;
627                break;
628            case 36:
629                call.address = (void *)((unsigned long)__builtin_return_address(36)&0xFFFFFF00);
630                if (!call.address)
631                    goto handle;
632                break;
633            case 37:
634                call.address = (void *)((unsigned long)__builtin_return_address(37)&0xFFFFFF00);
635                if (!call.address)
636                    goto handle;
637                break;
638            case 38:
639                call.address = (void *)((unsigned long)__builtin_return_address(38)&0xFFFFFF00);
640                if (!call.address)
641                    goto handle;
642                break;
643            case 39:
644                call.address = (void *)((unsigned long)__builtin_return_address(39)&0xFFFFFF00);
645                if (!call.address)
646                    goto handle;
647                break;
648            case 40:
649                call.address = (void *)((unsigned long)__builtin_return_address(40)&0xFFFFFF00);
650                if (!call.address)
651                    goto handle;
652                break;
653            case 41:
654                call.address = (void *)((unsigned long)__builtin_return_address(41)&0xFFFFFF00);
655                if (!call.address)
656                    goto handle;
657                break;
658            case 42:
659                call.address = (void *)((unsigned long)__builtin_return_address(42)&0xFFFFFF00);
660                if (!call.address)
661                    goto handle;
662                break;
663            case 43:
664                call.address = (void *)((unsigned long)__builtin_return_address(43)&0xFFFFFF00);
665                if (!call.address)
666                    goto handle;
667                break;
668            case 44:
669                call.address = (void *)((unsigned long)__builtin_return_address(44)&0xFFFFFF00);
670                if (!call.address)
671                    goto handle;
672                break;
673            case 45:
674                call.address = (void *)((unsigned long)__builtin_return_address(45)&0xFFFFFF00);
675                if (!call.address)
676                    goto handle;
677                break;
678            case 46:
679                call.address = (void *)((unsigned long)__builtin_return_address(46)&0xFFFFFF00);
680                if (!call.address)
681                    goto handle;
682                break;
683            case 47:
684                call.address = (void *)((unsigned long)__builtin_return_address(47)&0xFFFFFF00);
685                if (!call.address)
686                    goto handle;
687                break;
688            case 48:
689                call.address = (void *)((unsigned long)__builtin_return_address(48)&0xFFFFFF00);
690                if (!call.address)
691                    goto handle;
692                break;
693            case 49:
694                call.address = (void *)((unsigned long)__builtin_return_address(49)&0xFFFFFF00);
695                if (!call.address)
696                    goto handle;
697                break;
698            case 50:
699                call.address = (void *)((unsigned long)__builtin_return_address(50)&0xFFFFFF00);
700                if (!call.address)
701                    goto handle;
702                break;
703            case 51:
704                call.address = (void *)((unsigned long)__builtin_return_address(51)&0xFFFFFF00);
705                if (!call.address)
706                    goto handle;
707                break;
708            case 52:
709                call.address = (void *)((unsigned long)__builtin_return_address(52)&0xFFFFFF00);
710                if (!call.address)
711                    goto handle;
712                break;
713            case 53:
714                call.address = (void *)((unsigned long)__builtin_return_address(53)&0xFFFFFF00);
715                if (!call.address)
716                    goto handle;
717                break;
718            case 54:
719                call.address = (void *)((unsigned long)__builtin_return_address(54)&0xFFFFFF00);
720                if (!call.address)
721                    goto handle;
722                break;
723            case 55:
724                call.address = (void *)((unsigned long)__builtin_return_address(55)&0xFFFFFF00);
725                if (!call.address)
726                    goto handle;
727                break;
728            case 56:
729                call.address = (void *)((unsigned long)__builtin_return_address(56)&0xFFFFFF00);
730                if (!call.address)
731                    goto handle;
732                break;
733            case 57:
734                call.address = (void *)((unsigned long)__builtin_return_address(57)&0xFFFFFF00);
735                if (!call.address)
736                    goto handle;
737                break;
738            case 58:
739                call.address = (void *)((unsigned long)__builtin_return_address(58)&0xFFFFFF00);
740                if (!call.address)
741                    goto handle;
742                break;
743            case 59:
744                call.address = (void *)((unsigned long)__builtin_return_address(59)&0xFFFFFF00);
745                if (!call.address)
746                    goto handle;
747                break;
748            case 60:
749                call.address = (void *)((unsigned long)__builtin_return_address(60)&0xFFFFFF00);
750                if (!call.address)
751                    goto handle;
752                break;
753            case 61:
754                call.address = (void *)((unsigned long)__builtin_return_address(61)&0xFFFFFF00);
755                if (!call.address)
756                    goto handle;
757                break;
758            case 62:
759                call.address = (void *)((unsigned long)__builtin_return_address(62)&0xFFFFFF00);
760                if (!call.address)
761                    goto handle;
762                break;
763            case 63:
764                call.address = (void *)((unsigned long)__builtin_return_address(63)&0xFFFFFF00);
765                if (!call.address)
766                    goto handle;
767                break;
768        }
769
770#ifdef DL_EXT
771        if (dladdr(call.address, &dlinfo) != 0) {
772            symname = dlinfo.dli_sname;
773
774            demangled = __cxa_demangle(symname, NULL, 0, &status);
775            if (status == 0 && demangled != NULL)
776                symname = demangled;
777
778            call.symbol = (symname != NULL) ? symname : "undefined";
779            call.object = (dlinfo.dli_fname != NULL) ? dlinfo.dli_fname : "undefined";
780
781
782            if (demangled)
783                free(demangled);
784        }
785#endif
786
787        callStack.push_back(call);
788    }
789
790handle:
791#endif
792
793#ifdef DL_EXT
794    instance();
795
796    ++instances;
797#endif
798
799    if (handlerMap[source])
800        handlers[source](source, this, handlerData[source]);
801
802    if (!exception::global_exeption_context.context)
803        abort();
804}
805
806//-------------------------------------------------------------------
807
808basic::~basic()
809{
810#ifdef DL_EXT
811    sync::stack tg;
812
813    --instances;
814
815    if (instances == 0) {
816        deinitModule deinit;
817
818        for (int i(0); i < MODULE_ENUMSIZE; ++i) {
819            if (!handlesOpened[i])
820                continue;
821
822            deinit = (deinitModule)dlsym(handles[i], "deinitExceptionBasicModule");
823            if (deinit != NULL)
824                deinit(cookies[i]);
825
826            handlesOpened[i] = false;
827
828#ifndef DL_FAST
829            dlclose(handles[i]);
830#endif
831        }
832    }
833#endif
834}
835
836//-------------------------------------------------------------------
837
838dodo::string
839basic::backtrace()
840{
841    dodo::string stack;
842
843    char str[32];
844
845    dodoArray<__call__>::iterator i = callStack.begin(), j = callStack.end();
846    for (; i != j; ++i) {
847        snprintf(str, 32, " [0x%lx]", (long)i->address);
848        stack += i->object + ": " + i->symbol + str + "\n";
849    }
850
851    return stack;
852}
853
854//-------------------------------------------------------------------
855
856basic::operator const dodo::string &()
857{
858    sync::stack tg;
859
860    return errStr;
861}
862
863//-------------------------------------------------------------------
864
865const char *
866basic::what() const
867{
868    sync::stack tg;
869
870    return errStr.data();
871}
872
873//-------------------------------------------------------------------
874
875void
876basic::setHandler(moduleEnum module,
877                  handler    handler,
878                  void       *data)
879{
880    sync::stack tg;
881
882#ifdef DL_EXT
883    instance();
884
885    if (handlesOpened[module]) {
886        deinitModule deinit;
887
888        deinit = (deinitModule)dlsym(handles[module], "deinitExceptionBasicModule");
889        if (deinit != NULL)
890            deinit(cookies[module]);
891
892#ifndef DL_FAST
893        dlclose(handles[module]);
894#endif
895
896        handlesOpened[module] = false;
897        handles[module] = NULL;
898    }
899#endif
900
901    handlers[module] = handler;
902    handlerMap[module] = true;
903    handlerData[module] = data;
904}
905
906//-------------------------------------------------------------------
907
908void
909basic::setHandler(handler handler,
910                  void    *data)
911{
912    sync::stack tg;
913
914#ifdef DL_EXT
915    instance();
916
917    deinitModule deinit;
918#endif
919
920    for (int i(0); i < MODULE_ENUMSIZE; ++i) {
921#ifdef DL_EXT
922        if (handlesOpened[i]) {
923            deinit = (deinitModule)dlsym(handles[i], "deinitExceptionBasicModule");
924            if (deinit != NULL)
925                deinit(cookies[i]);
926
927#ifndef DL_FAST
928            dlclose(handles[i]);
929#endif
930
931            handlesOpened[i] = false;
932            handles[i] = NULL;
933        }
934#endif
935
936        handlers[i] = handler;
937        handlerMap[i] = true;
938        handlerData[i] = data;
939    }
940}
941
942//-------------------------------------------------------------------
943
944void
945basic::removeHandler(moduleEnum module)
946{
947    sync::stack tg;
948
949#ifdef DL_EXT
950    if (handlesOpened[module]) {
951        deinitModule deinit;
952
953        deinit = (deinitModule)dlsym(handles[module], "deinitExceptionBasicModule");
954        if (deinit != NULL)
955            deinit(cookies[module]);
956
957#ifndef DL_FAST
958        dlclose(handles[module]);
959#endif
960
961        handlesOpened[module] = false;
962        handles[module] = NULL;
963    }
964#endif
965
966    handlers[module] = NULL;
967    handlerMap[module] = false;
968    handlerData[module] = NULL;
969}
970
971//-------------------------------------------------------------------
972
973void
974basic::removeHandlers()
975{
976    sync::stack tg;
977
978#ifdef DL_EXT
979    deinitModule deinit;
980#endif
981
982    for (int i(0); i < MODULE_ENUMSIZE; ++i) {
983#ifdef DL_EXT
984        if (handlesOpened[i]) {
985            deinit = (deinitModule)dlsym(handles[i], "deinitExceptionBasicModule");
986            if (deinit != NULL)
987                deinit(cookies[i]);
988
989#ifndef DL_FAST
990            dlclose(handles[i]);
991#endif
992
993            handlesOpened[i] = false;
994            handles[i] = NULL;
995        }
996#endif
997
998        handlers[i] = NULL;
999        handlerMap[i] = false;
1000        handlerData[i] = NULL;
1001    }
1002}
1003
1004//-------------------------------------------------------------------
1005
1006#ifdef DL_EXT
1007void
1008basic::setHandler(const dodo::string &path,
1009                  void             *data,
1010                  void             *toInit)
1011{
1012    sync::stack tg;
1013
1014    instance();
1015
1016#ifdef DL_FAST
1017    void *h = dlopen(path.data(), RTLD_LAZY | RTLD_NODELETE);
1018#else
1019    void *h = dlopen(path.data(), RTLD_LAZY);
1020#endif
1021    if (h == NULL)
1022        return;
1023
1024    initModule init = (initModule)dlsym(h, "initExceptionBasicModule");
1025    if (init == NULL)
1026        return;
1027
1028    __module__ mod = init(toInit);
1029
1030    deinitModule deinit;
1031
1032    for (int i = 0; i < MODULE_ENUMSIZE; ++i) {
1033        if (!mod.modules[i])
1034            continue;
1035
1036        if (handlesOpened[i]) {
1037            deinit = (deinitModule)dlsym(handles[i], "deinitExceptionBasicModule");
1038            if (deinit != NULL)
1039                deinit(cookies[i]);
1040
1041#ifndef DL_FAST
1042            dlclose(handles[i]);
1043#endif
1044
1045            handlesOpened[i] = false;
1046            handles[i] = NULL;
1047        }
1048
1049
1050        handles[i] = h;
1051
1052        handler in = (handler)dlsym(handles[i], mod.hook);
1053        if (in == NULL)
1054            continue;
1055
1056        handlesOpened[i] = true;
1057        memcpy(cookies[i], mod.cookie, 32);
1058
1059        handlers[i] = in;
1060        handlerMap[i] = true;
1061        handlerData[i] = data;
1062    }
1063}
1064
1065//-------------------------------------------------------------------
1066
1067basic::__module__
1068basic::module(const dodo::string &module,
1069              void             *toInit)
1070{
1071    sync::stack tg;
1072
1073#ifdef DL_FAST
1074    void *handle = dlopen(module.data(), RTLD_LAZY | RTLD_NODELETE);
1075#else
1076    void *handle = dlopen(module.data(), RTLD_LAZY);
1077#endif
1078    if (handle == NULL)
1079        return __module__();
1080
1081    initModule init = (initModule)dlsym(handle, "initExceptionBasicModule");
1082    if (init == NULL)
1083        return __module__();
1084
1085    __module__ mod = init(toInit);
1086
1087        deinitModule deinit = (deinitModule)dlsym(handle, "deinitExceptionBasicModule");
1088        if (deinit != NULL)
1089                deinit(mod.cookie);
1090
1091#ifndef DL_FAST
1092    if (dlclose(handle) != 0)
1093        return mod;
1094
1095#endif
1096
1097    return mod;
1098}
1099#endif
1100
1101//-------------------------------------------------------------------
1102
1103void *
1104basic::operator new(size_t size UNUSED,
1105        void *mem)
1106{
1107    return mem;
1108}
1109
1110//-------------------------------------------------------------------
1111
1112void *
1113basic::operator new(size_t size)
1114{
1115    return new char [size];
1116}
1117
1118//-------------------------------------------------------------------
1119
1120void
1121basic::operator delete(void *p)
1122{
1123    if (p != (void *)&exeption_storage)
1124        delete [] (char *)p;
1125}
1126
1127//-------------------------------------------------------------------
1128
Note: See TracBrowser for help on using the repository browser.