~harrison-fisk/drizzle/import-google-innodb-smp-patch

« back to all changes in this revision

Viewing changes to drizzled/functions/lock.cc

  • Committer: Brian Aker
  • Date: 2008-10-29 13:44:52 UTC
  • mfrom: (520.4.24 devel)
  • Revision ID: brian@tangent.org-20081029134452-1nm5k9jw9mao0r1k
Merge from Monty

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008 Sun Microsystems
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; version 2 of the License.
 
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 St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
 
19
 
 
20
#include <drizzled/server_includes.h>
 
21
#include CSTDINT_H
 
22
#include <drizzled/functions/lock.h>
 
23
 
 
24
/*
 
25
** User level locks
 
26
*/
 
27
 
 
28
pthread_mutex_t LOCK_user_locks;
 
29
static HASH hash_user_locks;
 
30
 
 
31
class User_level_lock
 
32
{
 
33
  unsigned char *key;
 
34
  size_t key_length;
 
35
 
 
36
public:
 
37
  int count;
 
38
  bool locked;
 
39
  pthread_cond_t cond;
 
40
  my_thread_id thread_id;
 
41
  void set_thread(Session *session) { thread_id= session->thread_id; }
 
42
 
 
43
  User_level_lock(const unsigned char *key_arg,uint32_t length, ulong id)
 
44
    :key_length(length),count(1),locked(1), thread_id(id)
 
45
  {
 
46
    key= (unsigned char*) my_memdup(key_arg,length,MYF(0));
 
47
    pthread_cond_init(&cond,NULL);
 
48
    if (key)
 
49
    {
 
50
      if (my_hash_insert(&hash_user_locks,(unsigned char*) this))
 
51
      {
 
52
        free(key);
 
53
        key=0;
 
54
      }
 
55
    }
 
56
  }
 
57
  ~User_level_lock()
 
58
  {
 
59
    if (key)
 
60
    {
 
61
      hash_delete(&hash_user_locks,(unsigned char*) this);
 
62
      free(key);
 
63
    }
 
64
    pthread_cond_destroy(&cond);
 
65
  }
 
66
  inline bool initialized() { return key != 0; }
 
67
 
 
68
  friend void item_user_lock_release(User_level_lock *ull);
 
69
  friend unsigned char *ull_get_key(const User_level_lock *ull, size_t *length,
 
70
                            bool not_used);
 
71
};
 
72
 
 
73
unsigned char *ull_get_key(const User_level_lock *ull, size_t *length,
 
74
                   bool not_used __attribute__((unused)))
 
75
{
 
76
  *length= ull->key_length;
 
77
  return ull->key;
 
78
}
 
79
 
 
80
 
 
81
void item_user_lock_release(User_level_lock *ull)
 
82
{
 
83
  ull->locked=0;
 
84
  ull->thread_id= 0;
 
85
  if (--ull->count)
 
86
    pthread_cond_signal(&ull->cond);
 
87
  else
 
88
    delete ull;
 
89
}
 
90
 
 
91
 
 
92
 
 
93
/**
 
94
  Check a user level lock.
 
95
 
 
96
  Sets null_value=true on error.
 
97
 
 
98
  @retval
 
99
    1           Available
 
100
  @retval
 
101
    0           Already taken, or error
 
102
*/
 
103
 
 
104
int64_t Item_func_is_free_lock::val_int()
 
105
{
 
106
  assert(fixed == 1);
 
107
  String *res=args[0]->val_str(&value);
 
108
  User_level_lock *ull;
 
109
 
 
110
  null_value=0;
 
111
  if (!res || !res->length())
 
112
  {
 
113
    null_value=1;
 
114
    return 0;
 
115
  }
 
116
 
 
117
  pthread_mutex_lock(&LOCK_user_locks);
 
118
  ull= (User_level_lock *) hash_search(&hash_user_locks, (unsigned char*) res->ptr(),
 
119
                                       (size_t) res->length());
 
120
  pthread_mutex_unlock(&LOCK_user_locks);
 
121
  if (!ull || !ull->locked)
 
122
    return 1;
 
123
  return 0;
 
124
}
 
125
 
 
126
int64_t Item_func_is_used_lock::val_int()
 
127
{
 
128
  assert(fixed == 1);
 
129
  String *res=args[0]->val_str(&value);
 
130
  User_level_lock *ull;
 
131
 
 
132
  null_value=1;
 
133
  if (!res || !res->length())
 
134
    return 0;
 
135
 
 
136
  pthread_mutex_lock(&LOCK_user_locks);
 
137
  ull= (User_level_lock *) hash_search(&hash_user_locks, (unsigned char*) res->ptr(),
 
138
                                       (size_t) res->length());
 
139
  pthread_mutex_unlock(&LOCK_user_locks);
 
140
  if (!ull || !ull->locked)
 
141
    return 0;
 
142
 
 
143
  null_value=0;
 
144
  return ull->thread_id;
 
145
}
 
146
 
 
147