Skip to content
This repository was archived by the owner on Sep 3, 2019. It is now read-only.

Commit 4262513

Browse files
Kiran Pawaraaronp24
authored andcommitted
vdpau_wrapper.c: Track dynamic library handles and free them on exit using __attribute__((destructor))
Signed-off-by: Kiran Pawar <[email protected]> Tested-by: Aaron Plattner <[email protected]> Signed-off-by: Aaron Plattner <[email protected]>
1 parent c4a2273 commit 4262513

File tree

1 file changed

+64
-23
lines changed

1 file changed

+64
-23
lines changed

src/vdpau_wrapper.c

Lines changed: 64 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,17 @@ typedef void SetDllHandle(
4040
void * driver_dll_handle
4141
);
4242

43+
static void * _vdp_backend_dll;
44+
static void * _vdp_trace_dll;
45+
static void * _vdp_driver_dll;
46+
static VdpDeviceCreateX11 * _vdp_imp_device_create_x11_proc;
47+
48+
#if defined(__GNUC__)
49+
50+
static void _vdp_close_driver(void) __attribute__((destructor));
51+
52+
#endif
53+
4354
#if DEBUG
4455

4556
static void _vdp_wrapper_error_breakpoint(char const * file, int line, char const * function)
@@ -87,23 +98,16 @@ static char * _vdp_get_driver_name_from_dri2(
8798
return driver_name;
8899
}
89100

90-
VdpStatus vdp_device_create_x11(
101+
static VdpStatus _vdp_open_driver(
91102
Display * display,
92-
int screen,
93-
/* output parameters follow */
94-
VdpDevice * device,
95-
VdpGetProcAddress * * get_proc_address
96-
)
103+
int screen)
97104
{
98105
char const * vdpau_driver;
99106
char * vdpau_driver_dri2 = NULL;
100107
char vdpau_driver_lib[PATH_MAX];
101-
void * backend_dll;
102108
char const * vdpau_trace;
103109
char const * func_name;
104110

105-
VdpDeviceCreateX11 * vdp_imp_device_create_x11;
106-
107111
vdpau_driver = getenv("VDPAU_DRIVER");
108112
if (!vdpau_driver) {
109113
vdpau_driver = vdpau_driver_dri2 =
@@ -125,40 +129,42 @@ VdpStatus vdp_device_create_x11(
125129
return VDP_STATUS_NO_IMPLEMENTATION;
126130
}
127131

128-
backend_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL);
129-
if (!backend_dll) {
132+
_vdp_driver_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL);
133+
if (!_vdp_driver_dll) {
130134
/* Try again using the old path, which is guaranteed to fit in PATH_MAX
131135
* if the complete path fit above. */
132136
snprintf(vdpau_driver_lib, sizeof(vdpau_driver_lib), DRIVER_LIB_FORMAT,
133137
"", vdpau_driver, "");
134-
backend_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL);
138+
_vdp_driver_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL);
135139
}
136140

137141
if (vdpau_driver_dri2) {
138142
XFree(vdpau_driver_dri2);
139143
vdpau_driver_dri2 = NULL;
140144
}
141145

142-
if (!backend_dll) {
146+
if (!_vdp_driver_dll) {
143147
fprintf(stderr, "Failed to open VDPAU backend %s\n", dlerror());
144148
_VDP_ERROR_BREAKPOINT();
145149
return VDP_STATUS_NO_IMPLEMENTATION;
146150
}
147151

152+
_vdp_backend_dll = _vdp_driver_dll;
153+
148154
vdpau_trace = getenv("VDPAU_TRACE");
149155
if (vdpau_trace && atoi(vdpau_trace)) {
150-
void * trace_dll;
151156
SetDllHandle * set_dll_handle;
152157

153-
trace_dll = dlopen(VDPAU_MODULEDIR "/libvdpau_trace.so.1", RTLD_NOW | RTLD_GLOBAL);
154-
if (!trace_dll) {
158+
_vdp_trace_dll = dlopen(VDPAU_MODULEDIR "/libvdpau_trace.so.1",
159+
RTLD_NOW | RTLD_GLOBAL);
160+
if (!_vdp_trace_dll) {
155161
fprintf(stderr, "Failed to open VDPAU trace library %s\n", dlerror());
156162
_VDP_ERROR_BREAKPOINT();
157163
return VDP_STATUS_NO_IMPLEMENTATION;
158164
}
159165

160166
set_dll_handle = (SetDllHandle*)dlsym(
161-
trace_dll,
167+
_vdp_trace_dll,
162168
"vdp_trace_set_backend_handle"
163169
);
164170
if (!set_dll_handle) {
@@ -167,27 +173,62 @@ VdpStatus vdp_device_create_x11(
167173
return VDP_STATUS_NO_IMPLEMENTATION;
168174
}
169175

170-
set_dll_handle(backend_dll);
176+
set_dll_handle(_vdp_backend_dll);
171177

172-
backend_dll = trace_dll;
178+
_vdp_backend_dll = _vdp_trace_dll;
173179

174180
func_name = "vdp_trace_device_create_x11";
175181
}
176182
else {
177183
func_name = "vdp_imp_device_create_x11";
178184
}
179185

180-
vdp_imp_device_create_x11 = (VdpDeviceCreateX11*)dlsym(
181-
backend_dll,
186+
_vdp_imp_device_create_x11_proc = (VdpDeviceCreateX11*)dlsym(
187+
_vdp_backend_dll,
182188
func_name
183189
);
184-
if (!vdp_imp_device_create_x11) {
190+
if (!_vdp_imp_device_create_x11_proc) {
185191
fprintf(stderr, "%s\n", dlerror());
186192
_VDP_ERROR_BREAKPOINT();
187193
return VDP_STATUS_NO_IMPLEMENTATION;
188194
}
189195

190-
return vdp_imp_device_create_x11(
196+
return VDP_STATUS_OK;
197+
}
198+
199+
static void _vdp_close_driver(void)
200+
{
201+
if (_vdp_driver_dll) {
202+
dlclose(_vdp_driver_dll);
203+
_vdp_driver_dll = NULL;
204+
}
205+
if (_vdp_trace_dll) {
206+
dlclose(_vdp_trace_dll);
207+
_vdp_trace_dll = NULL;
208+
}
209+
_vdp_backend_dll = NULL;
210+
_vdp_imp_device_create_x11_proc = NULL;
211+
}
212+
213+
VdpStatus vdp_device_create_x11(
214+
Display * display,
215+
int screen,
216+
/* output parameters follow */
217+
VdpDevice * device,
218+
VdpGetProcAddress * * get_proc_address
219+
)
220+
{
221+
VdpStatus status;
222+
223+
if (!_vdp_imp_device_create_x11_proc) {
224+
status = _vdp_open_driver(display, screen);
225+
if (status != VDP_STATUS_OK) {
226+
_vdp_close_driver();
227+
return status;
228+
}
229+
}
230+
231+
return _vdp_imp_device_create_x11_proc(
191232
display,
192233
screen,
193234
device,

0 commit comments

Comments
 (0)