• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 2010 The Android Open Source Project
3   *
4   * Licensed under the Apache License, Version 2.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *      http://www.apache.org/licenses/LICENSE-2.0
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  /* ThreadSync implementation */
18  
19  #include "sles_allinclusive.h"
20  
21  
IThreadSync_EnterCriticalSection(SLThreadSyncItf self)22  static SLresult IThreadSync_EnterCriticalSection(SLThreadSyncItf self)
23  {
24      SL_ENTER_INTERFACE
25  
26      IThreadSync *thiz = (IThreadSync *) self;
27      interface_lock_exclusive(thiz);
28      for (;;) {
29          if (thiz->mInCriticalSection) {
30              if (!pthread_equal(thiz->mOwner, pthread_self())) {
31                  ++thiz->mWaiting;
32                  interface_cond_wait(thiz);
33                  continue;
34              }
35              // nested locks are not allowed
36              result = SL_RESULT_PRECONDITIONS_VIOLATED;
37              break;
38          }
39          thiz->mInCriticalSection = SL_BOOLEAN_TRUE;
40          thiz->mOwner = pthread_self();
41          result = SL_RESULT_SUCCESS;
42          break;
43      }
44      interface_unlock_exclusive(thiz);
45  
46      SL_LEAVE_INTERFACE
47  }
48  
49  
IThreadSync_ExitCriticalSection(SLThreadSyncItf self)50  static SLresult IThreadSync_ExitCriticalSection(SLThreadSyncItf self)
51  {
52      SL_ENTER_INTERFACE
53  
54      IThreadSync *thiz = (IThreadSync *) self;
55      interface_lock_exclusive(thiz);
56      if (!thiz->mInCriticalSection || !pthread_equal(thiz->mOwner, pthread_self())) {
57          result = SL_RESULT_PRECONDITIONS_VIOLATED;
58      } else {
59          thiz->mInCriticalSection = SL_BOOLEAN_FALSE;
60          memset(&thiz->mOwner, 0, sizeof(pthread_t));
61          if (thiz->mWaiting) {
62              --thiz->mWaiting;
63              interface_cond_signal(thiz);
64          }
65          result = SL_RESULT_SUCCESS;
66      }
67      interface_unlock_exclusive(thiz);
68  
69      SL_LEAVE_INTERFACE
70  }
71  
72  
73  static const struct SLThreadSyncItf_ IThreadSync_Itf = {
74      IThreadSync_EnterCriticalSection,
75      IThreadSync_ExitCriticalSection
76  };
77  
IThreadSync_init(void * self)78  void IThreadSync_init(void *self)
79  {
80      IThreadSync *thiz = (IThreadSync *) self;
81      thiz->mItf = &IThreadSync_Itf;
82      thiz->mInCriticalSection = SL_BOOLEAN_FALSE;
83      thiz->mWaiting = 0;
84      memset(&thiz->mOwner, 0, sizeof(pthread_t));
85  }
86  
IThreadSync_deinit(void * self)87  void IThreadSync_deinit(void *self)
88  {
89      IThreadSync *thiz = (IThreadSync *) self;
90      if (thiz->mInCriticalSection) {
91          SL_LOGW("ThreadSync::EnterCriticalSection was active at Engine::Destroy");
92      }
93  }
94