~malept/ubuntu/lucid/python2.6/dev-dependency-fix

« back to all changes in this revision

Viewing changes to Python/dynload_beos.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-02-13 12:51:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090213125100-uufgcb9yeqzujpqw
Tags: upstream-2.6.1
ImportĀ upstreamĀ versionĀ 2.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* Support for dynamic loading of extension modules */
 
3
 
 
4
#include <kernel/image.h>
 
5
#include <kernel/OS.h>
 
6
#include <stdlib.h>
 
7
 
 
8
#include "Python.h"
 
9
#include "importdl.h"
 
10
 
 
11
const struct filedescr _PyImport_DynLoadFiletab[] = {
 
12
        {".so", "rb", C_EXTENSION},
 
13
        {"module.so", "rb", C_EXTENSION},
 
14
        {0, 0}
 
15
};
 
16
 
 
17
#if defined(MAXPATHLEN) && !defined(_SYS_PARAM_H)
 
18
#undef MAXPATHLEN
 
19
#endif
 
20
 
 
21
#ifdef WITH_THREAD
 
22
#include "pythread.h"
 
23
static PyThread_type_lock beos_dyn_lock;
 
24
#endif
 
25
 
 
26
static PyObject *beos_dyn_images = NULL;
 
27
 
 
28
/* ----------------------------------------------------------------------
 
29
 * BeOS dynamic loading support
 
30
 *
 
31
 * This uses shared libraries, but BeOS has its own way of doing things
 
32
 * (much easier than dlfnc.h, from the look of things).  We'll use a
 
33
 * Python Dictionary object to store the images_ids so we can be very
 
34
 * nice and unload them when we exit.
 
35
 *
 
36
 * Note that this is thread-safe.  Probably irrelevent, because of losing
 
37
 * systems... Python probably disables threads while loading modules.
 
38
 * Note the use of "probably"!  Better to be safe than sorry. [chrish]
 
39
 *
 
40
 * As of 1.5.1 this should also work properly when you've configured
 
41
 * Python without thread support; the 1.5 version required it, which wasn't
 
42
 * very friendly.  Note that I haven't tested it without threading... why
 
43
 * would you want to avoid threads on BeOS? [chrish]
 
44
 *
 
45
 * As of 1.5.2, the PyImport_BeImageID() function has been removed; Donn
 
46
 * tells me it's not necessary anymore because of PyCObject_Import().
 
47
 * [chrish]
 
48
 */
 
49
 
 
50
/* Whack an item; the item is an image_id in disguise, so we'll call
 
51
 * unload_add_on() for it.
 
52
 */
 
53
static void beos_nuke_dyn( PyObject *item )
 
54
{
 
55
        status_t retval;
 
56
 
 
57
        if( item ) {
 
58
                image_id id = (image_id)PyInt_AsLong( item );
 
59
                
 
60
                retval = unload_add_on( id );
 
61
        }
 
62
}
 
63
 
 
64
/* atexit() handler that'll call unload_add_on() for every item in the
 
65
 * dictionary.
 
66
 */
 
67
static void beos_cleanup_dyn( void )
 
68
{
 
69
        if( beos_dyn_images ) {
 
70
                int idx;
 
71
                int list_size;
 
72
                PyObject *id_list;
 
73
 
 
74
#ifdef WITH_THREAD
 
75
                PyThread_acquire_lock( beos_dyn_lock, 1 );
 
76
#endif
 
77
 
 
78
                id_list = PyDict_Values( beos_dyn_images );
 
79
 
 
80
                list_size = PyList_Size( id_list );
 
81
                for( idx = 0; idx < list_size; idx++ ) {
 
82
                        PyObject *the_item;
 
83
                        
 
84
                        the_item = PyList_GetItem( id_list, idx );
 
85
                        beos_nuke_dyn( the_item );
 
86
                }
 
87
 
 
88
                PyDict_Clear( beos_dyn_images );
 
89
 
 
90
#ifdef WITH_THREAD
 
91
                PyThread_free_lock( beos_dyn_lock );
 
92
#endif
 
93
        }
 
94
}
 
95
 
 
96
/*
 
97
 * Initialize our dictionary, and the dictionary mutex.
 
98
 */
 
99
static void beos_init_dyn( void )
 
100
{
 
101
        /* We're protected from a race condition here by the atomic init_count
 
102
         * variable.
 
103
         */
 
104
        static int32 init_count = 0;
 
105
        int32 val;
 
106
 
 
107
        val = atomic_add( &init_count, 1 );
 
108
        if( beos_dyn_images == NULL && val == 0 ) {
 
109
                beos_dyn_images = PyDict_New();
 
110
#ifdef WITH_THREAD
 
111
                beos_dyn_lock = PyThread_allocate_lock();
 
112
#endif
 
113
                atexit( beos_cleanup_dyn );
 
114
        }
 
115
}
 
116
 
 
117
/*
 
118
 * Add an image_id to the dictionary; the module name of the loaded image
 
119
 * is the key.  Note that if the key is already in the dict, we unload
 
120
 * that image; this should allow reload() to work on dynamically loaded
 
121
 * modules (super-keen!).
 
122
 */
 
123
static void beos_add_dyn( char *name, image_id id )
 
124
{
 
125
        int retval;
 
126
        PyObject *py_id;
 
127
 
 
128
        if( beos_dyn_images == NULL ) {
 
129
                beos_init_dyn();
 
130
        }
 
131
 
 
132
#ifdef WITH_THREAD
 
133
        retval = PyThread_acquire_lock( beos_dyn_lock, 1 );
 
134
#endif
 
135
 
 
136
        /* If there's already an object with this key in the dictionary,
 
137
         * we're doing a reload(), so let's nuke it.
 
138
         */
 
139
        py_id = PyDict_GetItemString( beos_dyn_images, name );
 
140
        if( py_id ) {
 
141
                beos_nuke_dyn( py_id );
 
142
                retval = PyDict_DelItemString( beos_dyn_images, name );
 
143
        }
 
144
 
 
145
        py_id = PyInt_FromLong( (long)id );
 
146
        if( py_id ) {
 
147
                retval = PyDict_SetItemString( beos_dyn_images, name, py_id );
 
148
        }
 
149
 
 
150
#ifdef WITH_THREAD
 
151
        PyThread_release_lock( beos_dyn_lock );
 
152
#endif
 
153
}
 
154
 
 
155
 
 
156
 
 
157
dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
 
158
                                    const char *pathname, FILE *fp)
 
159
{
 
160
        dl_funcptr p;
 
161
        image_id the_id;
 
162
        status_t retval;
 
163
        char fullpath[PATH_MAX];
 
164
        char funcname[258];
 
165
 
 
166
        if( Py_VerboseFlag ) {
 
167
                printf( "load_add_on( %s )\n", pathname );
 
168
        }
 
169
 
 
170
        /* Hmm, this old bug appears to have regenerated itself; if the
 
171
         * path isn't absolute, load_add_on() will fail.  Reported to Be
 
172
         * April 21, 1998.
 
173
         */
 
174
        if( pathname[0] != '/' ) {
 
175
                (void)getcwd( fullpath, PATH_MAX );
 
176
                (void)strncat( fullpath, "/", PATH_MAX );
 
177
                (void)strncat( fullpath, pathname, PATH_MAX );
 
178
                        
 
179
                if( Py_VerboseFlag ) {
 
180
                        printf( "load_add_on( %s )\n", fullpath );
 
181
                }
 
182
        } else {
 
183
                (void)strcpy( fullpath, pathname );
 
184
        }
 
185
 
 
186
        the_id = load_add_on( fullpath );
 
187
        if( the_id < B_NO_ERROR ) {
 
188
                /* It's too bad load_add_on() doesn't set errno or something...
 
189
                 */
 
190
                char buff[256];  /* hate hard-coded string sizes... */
 
191
 
 
192
                if( Py_VerboseFlag ) {
 
193
                        printf( "load_add_on( %s ) failed", fullpath );
 
194
                }
 
195
 
 
196
                if( the_id == B_ERROR )
 
197
                        PyOS_snprintf( buff, sizeof(buff),
 
198
                                       "BeOS: Failed to load %.200s",
 
199
                                       fullpath );
 
200
                else
 
201
                        PyOS_snprintf( buff, sizeof(buff), 
 
202
                                       "Unknown error loading %.200s", 
 
203
                                       fullpath );
 
204
 
 
205
                PyErr_SetString( PyExc_ImportError, buff );
 
206
                return NULL;
 
207
        }
 
208
 
 
209
        PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
 
210
        if( Py_VerboseFlag ) {
 
211
                printf( "get_image_symbol( %s )\n", funcname );
 
212
        }
 
213
 
 
214
        retval = get_image_symbol( the_id, funcname, B_SYMBOL_TYPE_TEXT, &p );
 
215
        if( retval != B_NO_ERROR || p == NULL ) {
 
216
                /* That's bad, we can't find that symbol in the module...
 
217
                 */
 
218
                char buff[256];  /* hate hard-coded string sizes... */
 
219
 
 
220
                if( Py_VerboseFlag ) {
 
221
                        printf( "get_image_symbol( %s ) failed", funcname );
 
222
                }
 
223
 
 
224
                switch( retval ) {
 
225
                case B_BAD_IMAGE_ID:
 
226
                        PyOS_snprintf( buff, sizeof(buff),
 
227
                               "can't load init function for dynamic module: "
 
228
                               "Invalid image ID for %.180s", fullpath );
 
229
                        break;
 
230
                case B_BAD_INDEX:
 
231
                        PyOS_snprintf( buff, sizeof(buff),
 
232
                               "can't load init function for dynamic module: "
 
233
                               "Bad index for %.180s", funcname );
 
234
                        break;
 
235
                default:
 
236
                        PyOS_snprintf( buff, sizeof(buff),
 
237
                               "can't load init function for dynamic module: "
 
238
                               "Unknown error looking up %.180s", funcname );
 
239
                        break;
 
240
                }
 
241
 
 
242
                retval = unload_add_on( the_id );
 
243
 
 
244
                PyErr_SetString( PyExc_ImportError, buff );
 
245
                return NULL;
 
246
        }
 
247
 
 
248
        /* Save the module name and image ID for later so we can clean up
 
249
         * gracefully.
 
250
         */
 
251
        beos_add_dyn( fqname, the_id );
 
252
 
 
253
        return p;
 
254
}