• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "running_lock.h"
17 
18 #include <stdint.h>
19 #include <stdlib.h>
20 
21 #include <common.h>
22 #include <ohos_errno.h>
23 #include <pthread.h>
24 #include <securec.h>
25 
26 #include "hilog_wrapper.h"
27 #include "running_lock_entry.h"
28 #include "running_lock_framework.h"
29 
30 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
31 static BOOL g_inited = FALSE;
32 static Vector g_runningLocks;
33 
AddRunningLock(RunningLock * lock)34 static BOOL AddRunningLock(RunningLock *lock)
35 {
36     pthread_mutex_lock(&g_mutex);
37     if (g_inited == FALSE) {
38         g_runningLocks = VECTOR_Make(NULL, NULL);
39         g_inited = TRUE;
40     }
41     int16_t pos = VECTOR_Add(&g_runningLocks, (void *)lock);
42     if (pos == INVALID_INDEX) {
43         POWER_HILOGE("Failed to add lock to vector");
44         pthread_mutex_unlock(&g_mutex);
45         return FALSE;
46     }
47     POWER_HILOGD("Add running lock, name: %s, type: %d", lock->name, lock->type);
48     pthread_mutex_unlock(&g_mutex);
49     return TRUE;
50 }
51 
RemoveRunningLock(const RunningLock * lock)52 static BOOL RemoveRunningLock(const RunningLock *lock)
53 {
54     pthread_mutex_lock(&g_mutex);
55     int16_t pos = VECTOR_Find(&g_runningLocks, (void *)lock);
56     if (pos < 0) {
57         POWER_HILOGE("Non-existent running lock");
58         pthread_mutex_unlock(&g_mutex);
59         return FALSE;
60     }
61     VECTOR_Swap(&g_runningLocks, pos, NULL);
62     POWER_HILOGD("Remove running lock, name: %s, type: %d", lock->name, lock->type);
63     pthread_mutex_unlock(&g_mutex);
64     return TRUE;
65 }
66 
IsRunningLockExisted(const RunningLock * lock)67 static BOOL IsRunningLockExisted(const RunningLock *lock)
68 {
69     if (lock == NULL) {
70         POWER_HILOGE("Invalid running lock");
71         return FALSE;
72     }
73     pthread_mutex_lock(&g_mutex);
74     BOOL ret = (VECTOR_Find(&g_runningLocks, (void *)lock) >= 0) ? TRUE : FALSE;
75     pthread_mutex_unlock(&g_mutex);
76     return ret;
77 }
78 
CreateRunningLockEntry(const char * name,RunningLockType type,RunningLockFlag flag)79 static RunningLockEntry *CreateRunningLockEntry(const char *name, RunningLockType type, RunningLockFlag flag)
80 {
81     RunningLockEntry *entry = (RunningLockEntry *)malloc(sizeof(RunningLockEntry));
82     if (entry == NULL) {
83         POWER_HILOGE("Failed allocate running lock entry");
84         return NULL;
85     }
86     (void)memset_s(entry, sizeof(RunningLockEntry), 0, sizeof(RunningLockEntry));
87     InitIdentity(entry);
88     entry->lock.type = type;
89     entry->lock.flag = flag;
90     if(strcpy_s(entry->lock.name, sizeof(entry->lock.name), name) != EOK) {
91         free(entry);
92         return NULL;
93     }
94     return entry;
95 }
96 
DestroyRunningLockEntry(RunningLockEntry * entry)97 static inline void DestroyRunningLockEntry(RunningLockEntry *entry)
98 {
99     if (entry != NULL) {
100         POWER_HILOGD("Free entry: %p", entry);
101         free(entry);
102     }
103 }
104 
CreateRunningLock(const char * name,RunningLockType type,RunningLockFlag flag)105 const RunningLock *CreateRunningLock(const char *name, RunningLockType type, RunningLockFlag flag)
106 {
107     if ((name == NULL) || (type >= RUNNINGLOCK_BUTT)) {
108         POWER_HILOGE("Invalid running lock name");
109         return NULL;
110     }
111 
112     RunningLockEntry *entry = CreateRunningLockEntry(name, type, flag);
113     if (entry == NULL) {
114         POWER_HILOGE("Failed create running lock entry");
115         return NULL;
116     }
117     AddRunningLock(&entry->lock);
118     POWER_HILOGD("Create %s, pid: %u, token: %llu", name, entry->identity.pid, (long long)entry->identity.token);
119     return &entry->lock;
120 }
121 
AcquireRunningLock(const RunningLock * lock)122 BOOL AcquireRunningLock(const RunningLock *lock)
123 {
124     if (IsRunningLockExisted(lock) == FALSE) {
125         POWER_HILOGE("Non-existent running lock");
126         return FALSE;
127     }
128     RunningLockEntry *entry = GetRunningLockEntry(lock);
129     if (entry->status.isHolding == TRUE) {
130         POWER_HILOGD("Already acquired, name: %s", lock->name);
131         return TRUE;
132     }
133     entry->status.isHolding = AcquireRunningLockEntry(entry, -1);
134     return entry->status.isHolding;
135 }
136 
ReleaseRunningLock(const RunningLock * lock)137 BOOL ReleaseRunningLock(const RunningLock *lock)
138 {
139     if (IsRunningLockExisted(lock) == FALSE) {
140         POWER_HILOGE("Non-existent running lock");
141         return FALSE;
142     }
143     RunningLockEntry *entry = GetRunningLockEntry(lock);
144     if (entry->status.isHolding == FALSE) {
145         POWER_HILOGD("Already released, name: %s", lock->name);
146         return TRUE;
147     }
148     entry->status.isHolding = !ReleaseRunningLockEntry(entry);
149     return !entry->status.isHolding;
150 }
151 
DestroyRunningLock(const RunningLock * lock)152 void DestroyRunningLock(const RunningLock *lock)
153 {
154     if (lock == NULL) {
155         POWER_HILOGE("Invalid running lock");
156         return;
157     }
158     ReleaseRunningLock(lock);
159     if (RemoveRunningLock(lock) == TRUE) {
160         DestroyRunningLockEntry(GetRunningLockEntry(lock));
161     }
162 }
163 
IsRunningLockHolding(const RunningLock * lock)164 BOOL IsRunningLockHolding(const RunningLock *lock)
165 {
166     if (IsRunningLockExisted(lock) == FALSE) {
167         POWER_HILOGE("Non-existent running lock");
168         return FALSE;
169     }
170     RunningLockEntry *entry = GetRunningLockEntry(lock);
171     return entry->status.isHolding;
172 }
173