fixed bug, defer Unlock()