kinetic-c  v0.12.0
Seagate Kinetic Protocol Client Library for C
kinetic_resourcewaiter.c
Go to the documentation of this file.
1 /*
2 * kinetic-c
3 * Copyright (C) 2015 Seagate Technology.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 */
20 #include "kinetic_resourcewaiter.h"
22 #include "kinetic_logger.h"
23 #include <stdlib.h>
24 #include <assert.h>
25 #include <time.h>
26 #include <sys/time.h>
27 
28 void KineticResourceWaiter_Init(KineticResourceWaiter * const waiter)
29 {
30  KINETIC_ASSERT(waiter != NULL);
31  pthread_mutex_init(&waiter->mutex, NULL);
32  pthread_cond_init(&waiter->ready_cond, NULL);
33 }
34 
35 void KineticResourceWaiter_SetAvailable(KineticResourceWaiter * const waiter)
36 {
37  KINETIC_ASSERT(waiter != NULL);
38  pthread_mutex_lock(&waiter->mutex);
39 
40  waiter->ready = true;
41  if (waiter->num_waiting > 0) {
42  pthread_cond_signal(&waiter->ready_cond);
43  }
44 
45  pthread_mutex_unlock(&waiter->mutex);
46 }
47 
48 bool KineticResourceWaiter_WaitTilAvailable(KineticResourceWaiter * const waiter, uint32_t max_wait_sec)
49 {
50  KINETIC_ASSERT(waiter != NULL);
51  pthread_mutex_lock(&waiter->mutex);
52 
53  waiter->num_waiting++;
54 
55  struct timeval tv_current_time;
56  gettimeofday(&tv_current_time, NULL);
57  struct timespec ts_expire_time = {
58  .tv_sec = tv_current_time.tv_sec + max_wait_sec,
59  .tv_nsec = tv_current_time.tv_usec * 1000, // convert us to ns
60  };
61 
62  int rc = 0;
63  while (!waiter->ready && rc == 0) {
64  rc = pthread_cond_timedwait(&waiter->ready_cond, &waiter->mutex, &ts_expire_time);
65  }
66  waiter->num_waiting--;
67 
68  pthread_mutex_unlock(&waiter->mutex);
69 
70  return (rc == 0);
71 }
72 
73 void KineticResourceWaiter_Destroy(KineticResourceWaiter * const waiter)
74 {
75  KINETIC_ASSERT(waiter != NULL);
76  pthread_mutex_destroy(&waiter->mutex);
77  pthread_cond_destroy(&waiter->ready_cond);
78 }
void KineticResourceWaiter_SetAvailable(KineticResourceWaiter *const waiter)
#define KINETIC_ASSERT(cond)
bool KineticResourceWaiter_WaitTilAvailable(KineticResourceWaiter *const waiter, uint32_t max_wait_sec)
void KineticResourceWaiter_Init(KineticResourceWaiter *const waiter)
void KineticResourceWaiter_Destroy(KineticResourceWaiter *const waiter)