Esempio n. 1
0
int
reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate)
{
    const Elf_Rela *relalim;
    const Elf_Rela *rela;

    if (!obj->irelative)
	return (0);
    relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
    for (rela = obj->pltrela;  rela < relalim;  rela++) {
	Elf_Addr *where, target, *ptr;

	switch (ELF_R_TYPE(rela->r_info)) {
	case R_X86_64_JMP_SLOT:
	  break;

	case R_X86_64_IRELATIVE:
	  ptr = (Elf_Addr *)(obj->relocbase + rela->r_addend);
	  where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
	  lock_release(rtld_bind_lock, lockstate);
	  target = call_ifunc_resolver(ptr);
	  wlock_acquire(rtld_bind_lock, lockstate);
	  *where = target;
	  break;
	}
    }
    obj->irelative = false;
    return (0);
}
Esempio n. 2
0
int
reloc_gnu_ifunc(Obj_Entry *obj, int flags, RtldLockState *lockstate)
{
    const Elf_Rela *relalim;
    const Elf_Rela *rela;

    if (!obj->gnu_ifunc)
	return (0);
    relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
    for (rela = obj->pltrela;  rela < relalim;  rela++) {
	Elf_Addr *where, target;
	const Elf_Sym *def;
	const Obj_Entry *defobj;

	switch (ELF_R_TYPE(rela->r_info)) {
	case R_X86_64_JMP_SLOT:
	  where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
	  def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
		SYMLOOK_IN_PLT | flags, NULL, lockstate);
	  if (def == NULL)
	      return (-1);
	  if (ELF_ST_TYPE(def->st_info) != STT_GNU_IFUNC)
	      continue;
	  lock_release(rtld_bind_lock, lockstate);
	  target = (Elf_Addr)rtld_resolve_ifunc(defobj, def);
	  wlock_acquire(rtld_bind_lock, lockstate);
	  reloc_jmpslot(where, target, defobj, obj, (const Elf_Rel *)rela);
	  break;
	}
    }
    obj->gnu_ifunc = false;
    return (0);
}
Esempio n. 3
0
void
lock_upgrade(rtld_lock_t lock, RtldLockState *lockstate)
{

	if (lockstate == NULL)
		return;

	lock_release(lock, lockstate);
	wlock_acquire(lock, lockstate);
}
Esempio n. 4
0
void
_rtld_atfork_pre(int *locks)
{
	RtldLockState ls[2];

	wlock_acquire(rtld_phdr_lock, &ls[0]);
	rlock_acquire(rtld_bind_lock, &ls[1]);

	/* XXXKIB: I am really sorry for this. */
	locks[0] = ls[1].lockstate;
	locks[2] = ls[0].lockstate;
}
Esempio n. 5
0
void
_rtld_atfork_pre(int *locks)
{
	RtldLockState ls[2];

	if (locks == NULL)
		return;

	/*
	 * Warning: this does not work with the rtld compat locks
	 * above, since the thread signal mask is corrupted (set to
	 * all signals blocked) if two locks are taken in write mode.
	 * The caller of the _rtld_atfork_pre() must provide the
	 * working implementation of the locks, and libthr locks are
	 * fine.
	 */
	wlock_acquire(rtld_phdr_lock, &ls[0]);
	wlock_acquire(rtld_bind_lock, &ls[1]);

	/* XXXKIB: I am really sorry for this. */
	locks[0] = ls[1].lockstate;
	locks[2] = ls[0].lockstate;
}
Esempio n. 6
0
void
_rtld_atfork_pre(int *locks)
{
	RtldLockState ls[2];

	if (locks == NULL)
		return;

	/*
	 * Warning: this did not worked well with the rtld compat
	 * locks above, when the thread signal mask was corrupted (set
	 * to all signals blocked) if two locks were taken
	 * simultaneously in the write mode.  The caller of the
	 * _rtld_atfork_pre() must provide the working implementation
	 * of the locks anyway, and libthr locks are fine.
	 */
	wlock_acquire(rtld_phdr_lock, &ls[0]);
	wlock_acquire(rtld_bind_lock, &ls[1]);

	/* XXXKIB: I am really sorry for this. */
	locks[0] = ls[1].lockstate;
	locks[2] = ls[0].lockstate;
}
Esempio n. 7
0
int
reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
{
	const Elf_Rela *relalim;
	const Elf_Rela *rela;
	Elf_Addr *where, target, *ptr;

	if (!obj->irelative)
		return (0);
	relalim = (const Elf_Rela *)((const char *)obj->pltrela + obj->pltrelasize);
	for (rela = obj->pltrela;  rela < relalim;  rela++) {
		if (ELF_R_TYPE(rela->r_info) == R_AARCH64_IRELATIVE) {
			ptr = (Elf_Addr *)(obj->relocbase + rela->r_addend);
			where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
			lock_release(rtld_bind_lock, lockstate);
			target = call_ifunc_resolver(ptr);
			wlock_acquire(rtld_bind_lock, lockstate);
			*where = target;
		}
	}
	obj->irelative = false;
	return (0);
}
Esempio n. 8
0
int
reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate)
{
    const Elf_Rel *rellim;
    const Elf_Rel *rel;
    Elf_Addr *where, target;

    if (!obj->irelative)
	return (0);
    rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize);
    for (rel = obj->pltrel;  rel < rellim;  rel++) {
	switch (ELF_R_TYPE(rel->r_info)) {
	case R_386_IRELATIVE:
	  where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
	  lock_release(rtld_bind_lock, lockstate);
	  target = call_ifunc_resolver(obj->relocbase + *where);
	  wlock_acquire(rtld_bind_lock, lockstate);
	  *where = target;
	  break;
	}
    }
    obj->irelative = false;
    return (0);
}
Esempio n. 9
0
/*
   wvctl_register_mouse_cb

   This function should work in the same way as of the keyboard register
   callback function.

   Before the callback is added, a search is done in the list so no
   callbacks are inserted twice. One callback (identified only by
   the routine address) can only be inserted once to the list,
   otherwise this function will return error!
*/
wstatus
wvctl_register_mouse_cb(wvmouse_cb mousecb,void *param)
{
	void *mousecb_cpy;
	wstatus ws;
	jmlist_status jmls;
	wvmousecb_t *new_mousecbt;

	/* workaround for ISO C unsupport of void* to function pointer conversion,
	this will only work if sizeof(void*) == sizeof(wvmouse_cb) */
	memcpy((void*)&mousecb_cpy,(void*)&mousecb,sizeof(wvmouse_cb));

	if( wvctl_unloading ) {
		dbgprint(MOD_WVIEWCTL,__func__,"module is unloading, cannot register mouse callback now");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	if( !wvctl_loaded ) {
		dbgprint(MOD_WVIEWCTL,__func__,"cannot use this function while the module was not loaded yet");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	dbgprint(MOD_WVIEWCTL,__func__,"acquiring mouse callback list lock");
	ws = wlock_acquire(&mouse_cbl_lock);
	if( ws != WSTATUS_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"unable to acquire mouse callback list lock");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	dbgprint(MOD_WVIEWCTL,__func__,"looking up if callback mousecb=%p exists in the list",mousecb);
	jmlist_lookup_result lookup_result;
	jmls = jmlist_find(mouse_cbl,iwvctl_find_mousecb,mousecb_cpy,&lookup_result,0);
	if( jmls != WSTATUS_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"jmlist_find failed");
		goto release_and_fail;
	}
	
	if( lookup_result == jmlist_entry_found ) {
		dbgprint(MOD_WVIEWCTL,__func__,"callback with mousecb=%p already exists in the list",mousecb);
		goto release_and_fail;
	}
	
	new_mousecbt = (wvmousecb_t*)malloc(sizeof(wvmousecb_t));
	if( !new_mousecbt ) {
		dbgprint(MOD_WVIEWCTL,__func__,"malloc failed");
		goto release_and_fail;
	}
	
	dbgprint(MOD_WVIEWCTL,__func__,"allocated new mouse callback structure (new_mousecbt=%p)",new_mousecbt);
	
	new_mousecbt->cb = mousecb;
	new_mousecbt->param = param;
	
	dbgprint(MOD_WVIEWCTL,__func__,"filled new structure with cb=%p and param=%p",
			 new_mousecbt->cb,new_mousecbt->param);
	
	dbgprint(MOD_WVIEWCTL,__func__,"adding mouse callback structure to the list");
	jmls = jmlist_insert(mouse_cbl,new_mousecbt);
	
	dbgprint(MOD_WVIEWCTL,__func__,"releasing mouse callback list lock");
	ws = wlock_release(&mouse_cbl_lock);
	if( ws != WSTATUS_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"failed to release mouse callback list lock");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	if( jmls != JMLIST_ERROR_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"failed to add mouse callback to the list");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	dbgprint(MOD_WVIEWCTL,__func__,"mouse callback list lock released successfully");
	DBGRET_SUCCESS(MOD_WVIEWCTL);

release_and_fail:
	dbgprint(MOD_WVIEWCTL,__func__,"releasing mouse callback list lock");
	ws = wlock_release(&mouse_cbl_lock);
	if( ws != WSTATUS_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"failed to release lock");
	}
	DBGRET_FAILURE(MOD_WVIEWCTL);
}
Esempio n. 10
0
/*
   wvctl_unregister_keyboard_cb

   First it should check if wvctl module is unloading, if it is, ignore the call
   returning with failure. Then, acquire the keyboard callback list lock, so
   it can access to the keyboard list and remove the specific callback. Callbacks
   are identified only by the function address (keycb) so there shouldn't exist
   two callbacks inside the callback list with the same value (this should be
   checked in wvctl_register_keyboard_cb function when registering the callback).
   After acquiring the callback list lock, the first thing it does is to lookup
   for the entry in the callback list, if its not found report and return with
   failure, otherwise proceed to the removal of the entry in the list.

   Finally free the callback list lock.

*/
wstatus
wvctl_unregister_keyboard_cb(wvkeyboard_cb keycb)
{
	jmlist_status jmls;
	wstatus ws;
	void *keycb_cpy;
	wvkeyboardcb_t *keycbt_ptr;

	/* workaround for ISO C unsupport of void* to function pointer conversion,
	this will only work if sizeof(void*) == sizeof(wvkeyboard_cb) */
	memcpy((void*)&keycb_cpy,(void*)&keycb,sizeof(wvkeyboard_cb));

	if( wvctl_unloading ) {
		dbgprint(MOD_WVIEWCTL,__func__,"module is unloading, cannot unregister keyboard callback now");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	if( !wvctl_loaded ) {
		dbgprint(MOD_WVIEWCTL,__func__,"cannot use this function while the module was not loaded yet");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	dbgprint(MOD_WVIEWCTL,__func__,"acquiring keyboard callback list lock");
	ws = wlock_acquire(&keyboard_cbl_lock);
	if( ws != WSTATUS_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"unable to acquire keyboard callback list lock");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	dbgprint(MOD_WVIEWCTL,__func__,"looking up if callback keycb=%p exists in the list",keycb);
	jmlist_lookup_result lookup_result;
	jmls = jmlist_find(keyboard_cbl,iwvctl_find_keycb,keycb_cpy,&lookup_result,(void*)&keycbt_ptr);
	if( jmls != JMLIST_ERROR_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"jmlist_ptr_exists failed");
		goto release_and_fail;
	}

	if( lookup_result == jmlist_entry_not_found ) {
		dbgprint(MOD_WVIEWCTL,__func__,"the entry keycb=%p is not in the callback list",keycb);
		goto release_and_fail;
	}

	jmls = jmlist_remove_by_ptr(keyboard_cbl,keycbt_ptr);

	dbgprint(MOD_WVIEWCTL,__func__,"releasing keyboard callback list lock");
	ws = wlock_release(&keyboard_cbl_lock);
	if( ws != WSTATUS_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"failed to release lock");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	if( jmls != JMLIST_ERROR_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"failed to remove keyboard callback to the list");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	dbgprint(MOD_WVIEWCTL,__func__,"removed keyboard callback from the list successfully");

	free(keycbt_ptr);
	dbgprint(MOD_WVIEWCTL,__func__,"freed keyboard callback structure memory");

	DBGRET_SUCCESS(MOD_WVIEWCTL);

release_and_fail:
	dbgprint(MOD_WVIEWCTL,__func__,"releasing keyboard callback list lock");
	ws = wlock_release(&keyboard_cbl_lock);
	if( ws != WSTATUS_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"failed to release lock");
	}
	DBGRET_FAILURE(MOD_WVIEWCTL);
}
Esempio n. 11
0
/*
   wvctl_register_keyboard_cb

   First check if the module is unloading, if so, return with error since
   no callback should be registered in that state.

   Then, try to acquire the lock on keyboard callback list so exclusive
   access is granted. A lookup for existent entries with same keycb must
   be done in order to avoid duplicate entries in the list.
   
   If there is no entry with same keycb in the list, add the keyboard
   callback to the list.

   Finally free the keyboard list lock.
*/
wstatus
wvctl_register_keyboard_cb(wvkeyboard_cb keycb,void *param)
{
	wstatus ws;
	jmlist_status jmls;
	void *keycb_cpy;
	wvkeyboardcb_t *new_keycbt;

	memcpy((void*)&keycb_cpy,(void*)&keycb,sizeof(wvkeyboard_cb));

	dbgprint(MOD_WVIEWCTL,__func__,"called with keycb=%p and param=%p",keycb,param);

	if( wvctl_unloading ) {
		dbgprint(MOD_WVIEWCTL,__func__,"module is unloading, cannot register keyboard callback now");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	if( !wvctl_loaded ) {
		dbgprint(MOD_WVIEWCTL,__func__,"cannot use this function while the module was not loaded yet");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	dbgprint(MOD_WVIEWCTL,__func__,"acquiring keyboard callback list lock");
	ws = wlock_acquire(&keyboard_cbl_lock);
	if( ws != WSTATUS_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"unable to acquire keyboard callback list lock");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	dbgprint(MOD_WVIEWCTL,__func__,"looking up if callback keycb=%p exists in the list",keycb);
	jmlist_lookup_result lookup_result;
	jmls = jmlist_find(keyboard_cbl,iwvctl_find_keycb,keycb_cpy,&lookup_result,0);
	if( jmls != WSTATUS_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"jmlist_find failed");
		goto release_and_fail;
	}
	
	if( lookup_result == jmlist_entry_found ) {
		dbgprint(MOD_WVIEWCTL,__func__,"callback with keycb=%p already exists in the list",keycb);
		goto release_and_fail;
	}

	new_keycbt = (wvkeyboardcb_t*)malloc(sizeof(wvkeyboardcb_t));
	if( !new_keycbt ) {
		dbgprint(MOD_WVIEWCTL,__func__,"malloc failed");
		goto release_and_fail;
	}

	dbgprint(MOD_WVIEWCTL,__func__,"allocated new keyboard callback structure (new_keycbt=%p)",new_keycbt);

	new_keycbt->cb = keycb;
	new_keycbt->param = param;

	dbgprint(MOD_WVIEWCTL,__func__,"filled new structure with cb=%p and param=%p",
			new_keycbt->cb,new_keycbt->param);

	dbgprint(MOD_WVIEWCTL,__func__,"adding keyboard callback structure to the list");
	jmls = jmlist_insert(keyboard_cbl,new_keycbt);

	dbgprint(MOD_WVIEWCTL,__func__,"releasing keyboard callback list lock");
	ws = wlock_release(&keyboard_cbl_lock);
	if( ws != WSTATUS_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"failed to release lock");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	if( jmls != JMLIST_ERROR_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"failed to add keyboard callback to the list");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	dbgprint(MOD_WVIEWCTL,__func__,"keyboard lock released successfully");
	DBGRET_SUCCESS(MOD_WVIEWCTL);

release_and_fail:
	dbgprint(MOD_WVIEWCTL,__func__,"releasing keyboard callback list lock");
	ws = wlock_release(&keyboard_cbl_lock);
	if( ws != WSTATUS_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"failed to release lock");
	}
	DBGRET_FAILURE(MOD_WVIEWCTL);
}
Esempio n. 12
0
wstatus
wvctl_mouse_routine(wvmouse_t mouse,void *param)
{
	wstatus ws;
	jmlist_status jmls;
	wvmousecb_t *mousecbt_ptr;

	dbgprint(MOD_WVIEWCTL,__func__,"called with mouse.button=%d, mouse.coord=(%d,%d) and mouse.mode=%d",
			mouse.button,mouse.x,mouse.y,mouse.mode);

	if( ! wvctl_loaded ) {
		dbgprint(MOD_WVIEWCTL,__func__,"unexpected call to this function, module not loaded yet");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	if( wvctl_unloading ) {
		dbgprint(MOD_WVIEWCTL,__func__,"module is unloading, ignoring this call");
		DBGRET_SUCCESS(MOD_WVIEWCTL);
	}

	dbgprint(MOD_WVIEWCTL,__func__,"acquiring mouse callback list lock");
	ws = wlock_acquire(&mouse_cbl_lock);
	if( ws != WSTATUS_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"unable to acquire mouse callback list lock");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	/* now that we've the lock, parse the keybaord callback list */
	
	jmlist_index entry_count;

	jmls = jmlist_entry_count(mouse_cbl,&entry_count);
	if( jmls != JMLIST_ERROR_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"unable to get mouse callback list entry count!");
		goto free_lock_fail;
	}

	dbgprint(MOD_WVIEWCTL,__func__,"mouse callback list has %u entries now",entry_count);
	
	for( jmlist_index i = 0 ; i < entry_count ; i++ )
	{
		jmls = jmlist_get_by_index(mouse_cbl,i,(void*)&mousecbt_ptr);
		if( jmls != JMLIST_ERROR_SUCCESS ) {
			dbgprint(MOD_WVIEWCTL,__func__,"unable to get mouse callback list entry #%u",i);
			goto free_lock_fail;
		}

		/* call the client routine */
		dbgprint(MOD_WVIEWCTL,__func__,"calling mouse client routine %p (index %u, param=%p)",
				mousecbt_ptr->cb,i,mousecbt_ptr->param);
		mousecbt_ptr->cb(mouse,mousecbt_ptr->param);
		dbgprint(MOD_WVIEWCTL,__func__,"mouse client routine returned");
	}

	dbgprint(MOD_WVIEWCTL,__func__,"all mouse callbacks called, freeing lock");
	ws = wlock_release(&mouse_cbl_lock);
	if( ws != WSTATUS_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"failed to release mouse callback list lock");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	dbgprint(MOD_WVIEWCTL,__func__,"mouse lock released successfully");
	DBGRET_SUCCESS(MOD_WVIEWCTL);

free_lock_fail:
	wlock_release(&mouse_cbl_lock);
	DBGRET_FAILURE(MOD_WVIEWCTL);
}
Esempio n. 13
0
wstatus
wvctl_draw_routine(wvdraw_t draw,void *param)
{
	wstatus ws;
	jmlist_status jmls;
	wvdrawcb_t *drawcbt_ptr;

	dbgprint(MOD_WVIEWCTL,__func__,"called with draw.flags=%d",draw.flags);

	if( !wvctl_loaded ) {
		dbgprint(MOD_WVIEWCTL,__func__,"unexpected call to this function, module not loaded yet");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	if( wvctl_unloading ) {
		dbgprint(MOD_WVIEWCTL,__func__,"module is unloading, ignoring this call");
		DBGRET_SUCCESS(MOD_WVIEWCTL);
	}

	dbgprint(MOD_WVIEWCTL,__func__,"acquiring draw callback list lock");
	ws = wlock_acquire(&draw_cbl_lock);
	if( ws != WSTATUS_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"unable to acquire draw callback list lock");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	/* now that we've the lock, parse the drawbaord callback list */
	
	jmlist_index entry_count;

	jmls = jmlist_entry_count(draw_cbl,&entry_count);
	if( jmls != JMLIST_ERROR_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"unable to get draw callback list entry count!");
		goto free_lock_fail;
	}

	dbgprint(MOD_WVIEWCTL,__func__,"draw callback list has %u entries now",entry_count);
	
	for( jmlist_index i = 0 ; i < entry_count ; i++ )
	{
		jmls = jmlist_get_by_index(draw_cbl,i,(void*)&drawcbt_ptr);
		if( jmls != JMLIST_ERROR_SUCCESS ) {
			dbgprint(MOD_WVIEWCTL,__func__,"unable to get draw callback list entry #%u",i);
			goto free_lock_fail;
		}

		/* call the client routine */
		dbgprint(MOD_WVIEWCTL,__func__,"calling draw client routine %p (index %u, param=%p)",
				drawcbt_ptr->cb,i,drawcbt_ptr->param);
		drawcbt_ptr->cb(draw,drawcbt_ptr->param);
		dbgprint(MOD_WVIEWCTL,__func__,"draw client routine returned");
	}

	dbgprint(MOD_WVIEWCTL,__func__,"all draw callbacks called, freeing lock");
	ws = wlock_release(&draw_cbl_lock);
	if( ws != WSTATUS_SUCCESS ) {
		dbgprint(MOD_WVIEWCTL,__func__,"failed to release draw callback list lock");
		DBGRET_FAILURE(MOD_WVIEWCTL);
	}

	dbgprint(MOD_WVIEWCTL,__func__,"draw lock released successfully");
	DBGRET_SUCCESS(MOD_WVIEWCTL);

free_lock_fail:
	wlock_release(&draw_cbl_lock);
	DBGRET_FAILURE(MOD_WVIEWCTL);
}