| description | Learn more about: Warning C26117 | |
|---|---|---|
| title | Warning C26117 | |
| ms.date | 11/04/2016 | |
| f1_keywords |
|
|
| helpviewer_keywords |
|
|
| ms.assetid | cc7ebc8d-9826-4cad-a4d5-2d3ad5896734 |
Releasing unheld lock 'lock' in function 'func'.
Enforcement of syntactically scoped lock acquire and lock release pairs in C/C++ programs isn't performed by the language. A function may introduce a locking side effect by making an observable modification to the concurrency state. For example, a lock wrapper function increments the number of lock acquisitions, or lock count, for a given lock. You can annotate a function that has a side effect from a lock acquire or lock release by using _Acquires_lock_ or _Releases_lock_, respectively. Without such annotations, a function is expected not to change any lock count after it returns. If acquires and releases aren't balanced, they're considered to be orphaned. Warning C26117 is issued when a function that hasn't been annotated with _Releases_lock_ releases a lock that it doesn't hold, because the function must own the lock before it releases it.
The following example generates warning C26117 because the function ReleaseUnheldLock releases a lock that it doesn't necessarily hold—the state of flag is ambiguous—and there's no annotation that specifies that it should.
typedef struct _DATA
{
CRITICAL_SECTION cs;
} DATA;
int flag;
void ReleaseUnheldLock(DATA* p)
{
if (flag)
EnterCriticalSection(&p->cs);
// code ...
LeaveCriticalSection(&p->cs);
}The following code fixes the problem by guaranteeing that the released lock is also acquired under the same conditions.
typedef struct _DATA
{
CRITICAL_SECTION cs;
} DATA;
int flag;
void ReleaseUnheldLock(DATA* p)
{
if (flag)
{
EnterCriticalSection(&p->cs);
// code ...
LeaveCriticalSection(&p->cs);
}
}