annotate thread.c @ 3:0b6ac95a09bb default tip

Fix unix sockets support under FreeBSD.
author Maxim Dounin <mdounin@mdounin.ru>
date Wed, 03 Oct 2007 05:34:42 +0400
parents 30782bb1fc04
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
2 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
3 * Thread management for memcached.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
4 *
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
5 * $Id$
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
6 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
7 #include "memcached.h"
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
8 #include <stdio.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
9 #include <errno.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
10 #include <stdlib.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
11 #include <errno.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
12
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
13 #ifdef HAVE_MALLOC_H
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
14 #include <malloc.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
15 #endif
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
16
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
17 #ifdef HAVE_STRING_H
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
18 #include <string.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
19 #endif
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
20
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
21 #ifdef USE_THREADS
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
22
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
23 #include <pthread.h>
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
24
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
25 #define ITEMS_PER_ALLOC 64
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
26
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
27 /* An item in the connection queue. */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
28 typedef struct conn_queue_item CQ_ITEM;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
29 struct conn_queue_item {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
30 int sfd;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
31 int init_state;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
32 int event_flags;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
33 int read_buffer_size;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
34 int is_udp;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
35 CQ_ITEM *next;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
36 };
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
37
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
38 /* A connection queue. */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
39 typedef struct conn_queue CQ;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
40 struct conn_queue {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
41 CQ_ITEM *head;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
42 CQ_ITEM *tail;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
43 pthread_mutex_t lock;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
44 pthread_cond_t cond;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
45 };
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
46
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
47 /* Lock for connection freelist */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
48 static pthread_mutex_t conn_lock;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
49
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
50 /* Lock for cache operations (item_*, assoc_*) */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
51 static pthread_mutex_t cache_lock;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
52
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
53 /* Lock for slab allocator operations */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
54 static pthread_mutex_t slabs_lock;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
55
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
56 /* Lock for global stats */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
57 static pthread_mutex_t stats_lock;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
58
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
59 /* Free list of CQ_ITEM structs */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
60 static CQ_ITEM *cqi_freelist;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
61 static pthread_mutex_t cqi_freelist_lock;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
62
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
63 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
64 * Each libevent instance has a wakeup pipe, which other threads
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
65 * can use to signal that they've put a new connection on its queue.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
66 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
67 typedef struct {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
68 pthread_t thread_id; /* unique ID of this thread */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
69 struct event_base *base; /* libevent handle this thread uses */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
70 struct event notify_event; /* listen event for notify pipe */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
71 int notify_receive_fd; /* receiving end of notify pipe */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
72 int notify_send_fd; /* sending end of notify pipe */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
73 CQ new_conn_queue; /* queue of new connections to handle */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
74 } LIBEVENT_THREAD;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
75
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
76 static LIBEVENT_THREAD *threads;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
77
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
78 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
79 * Number of threads that have finished setting themselves up.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
80 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
81 static int init_count = 0;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
82 static pthread_mutex_t init_lock;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
83 static pthread_cond_t init_cond;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
84
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
85
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
86 static void thread_libevent_process(int fd, short which, void *arg);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
87
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
88 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
89 * Initializes a connection queue.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
90 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
91 static void cq_init(CQ *cq) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
92 pthread_mutex_init(&cq->lock, NULL);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
93 pthread_cond_init(&cq->cond, NULL);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
94 cq->head = NULL;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
95 cq->tail = NULL;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
96 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
97
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
98 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
99 * Waits for work on a connection queue.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
100 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
101 static CQ_ITEM *cq_pop(CQ *cq) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
102 CQ_ITEM *item;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
103
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
104 pthread_mutex_lock(&cq->lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
105 while (NULL == cq->head)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
106 pthread_cond_wait(&cq->cond, &cq->lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
107 item = cq->head;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
108 cq->head = item->next;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
109 if (NULL == cq->head)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
110 cq->tail = NULL;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
111 pthread_mutex_unlock(&cq->lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
112
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
113 return item;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
114 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
115
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
116 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
117 * Looks for an item on a connection queue, but doesn't block if there isn't
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
118 * one.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
119 * Returns the item, or NULL if no item is available
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
120 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
121 static CQ_ITEM *cq_peek(CQ *cq) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
122 CQ_ITEM *item;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
123
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
124 pthread_mutex_lock(&cq->lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
125 item = cq->head;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
126 if (NULL != item) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
127 cq->head = item->next;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
128 if (NULL == cq->head)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
129 cq->tail = NULL;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
130 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
131 pthread_mutex_unlock(&cq->lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
132
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
133 return item;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
134 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
135
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
136 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
137 * Adds an item to a connection queue.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
138 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
139 static void cq_push(CQ *cq, CQ_ITEM *item) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
140 item->next = NULL;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
141
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
142 pthread_mutex_lock(&cq->lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
143 if (NULL == cq->tail)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
144 cq->head = item;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
145 else
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
146 cq->tail->next = item;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
147 cq->tail = item;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
148 pthread_cond_signal(&cq->cond);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
149 pthread_mutex_unlock(&cq->lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
150 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
151
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
152 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
153 * Returns a fresh connection queue item.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
154 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
155 static CQ_ITEM *cqi_new() {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
156 CQ_ITEM *item = NULL;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
157 pthread_mutex_lock(&cqi_freelist_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
158 if (cqi_freelist) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
159 item = cqi_freelist;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
160 cqi_freelist = item->next;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
161 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
162 pthread_mutex_unlock(&cqi_freelist_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
163
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
164 if (NULL == item) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
165 int i;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
166
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
167 /* Allocate a bunch of items at once to reduce fragmentation */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
168 item = malloc(sizeof(CQ_ITEM) * ITEMS_PER_ALLOC);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
169 if (NULL == item)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
170 return NULL;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
171
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
172 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
173 * Link together all the new items except the first one
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
174 * (which we'll return to the caller) for placement on
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
175 * the freelist.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
176 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
177 for (i = 2; i < ITEMS_PER_ALLOC; i++)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
178 item[i - 1].next = &item[i];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
179
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
180 pthread_mutex_lock(&cqi_freelist_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
181 item[ITEMS_PER_ALLOC - 1].next = cqi_freelist;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
182 cqi_freelist = &item[1];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
183 pthread_mutex_unlock(&cqi_freelist_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
184 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
185
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
186 return item;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
187 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
188
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
189
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
190 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
191 * Frees a connection queue item (adds it to the freelist.)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
192 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
193 static void cqi_free(CQ_ITEM *item) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
194 pthread_mutex_lock(&cqi_freelist_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
195 item->next = cqi_freelist;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
196 cqi_freelist = item;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
197 pthread_mutex_unlock(&cqi_freelist_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
198 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
199
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
200
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
201 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
202 * Creates a worker thread.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
203 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
204 static void create_worker(void *(*func)(void *), void *arg) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
205 pthread_t thread;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
206 pthread_attr_t attr;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
207 int ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
208
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
209 pthread_attr_init(&attr);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
210
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
211 if ((ret = pthread_create(&thread, &attr, func, arg)) != 0) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
212 fprintf(stderr, "Can't create thread: %s\n",
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
213 strerror(ret));
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
214 exit(1);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
215 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
216 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
217
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
218
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
219 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
220 * Pulls a conn structure from the freelist, if one is available.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
221 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
222 conn *mt_conn_from_freelist() {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
223 conn *c;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
224
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
225 pthread_mutex_lock(&conn_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
226 c = do_conn_from_freelist();
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
227 pthread_mutex_unlock(&conn_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
228
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
229 return c;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
230 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
231
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
232
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
233 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
234 * Adds a conn structure to the freelist.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
235 *
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
236 * Returns 0 on success, 1 if the structure couldn't be added.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
237 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
238 int mt_conn_add_to_freelist(conn *c) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
239 int result;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
240
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
241 pthread_mutex_lock(&conn_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
242 result = do_conn_add_to_freelist(c);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
243 pthread_mutex_unlock(&conn_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
244
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
245 return result;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
246 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
247
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
248 /****************************** LIBEVENT THREADS *****************************/
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
249
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
250 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
251 * Set up a thread's information.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
252 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
253 static void setup_thread(LIBEVENT_THREAD *me) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
254 if (! me->base) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
255 me->base = event_init();
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
256 if (! me->base) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
257 fprintf(stderr, "Can't allocate event base\n");
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
258 exit(1);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
259 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
260 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
261
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
262 /* Listen for notifications from other threads */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
263 event_set(&me->notify_event, me->notify_receive_fd,
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
264 EV_READ | EV_PERSIST, thread_libevent_process, me);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
265 event_base_set(me->base, &me->notify_event);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
266
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
267 if (event_add(&me->notify_event, 0) == -1) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
268 fprintf(stderr, "Can't monitor libevent notify pipe\n");
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
269 exit(1);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
270 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
271
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
272 cq_init(&me->new_conn_queue);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
273 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
274
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
275
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
276 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
277 * Worker thread: main event loop
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
278 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
279 static void *worker_libevent(void *arg) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
280 LIBEVENT_THREAD *me = arg;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
281
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
282 /* Any per-thread setup can happen here; thread_init() will block until
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
283 * all threads have finished initializing.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
284 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
285
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
286 pthread_mutex_lock(&init_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
287 init_count++;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
288 pthread_cond_signal(&init_cond);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
289 pthread_mutex_unlock(&init_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
290
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
291 return (void*) event_base_loop(me->base, 0);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
292 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
293
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
294
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
295 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
296 * Processes an incoming "handle a new connection" item. This is called when
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
297 * input arrives on the libevent wakeup pipe.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
298 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
299 static void thread_libevent_process(int fd, short which, void *arg) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
300 LIBEVENT_THREAD *me = arg;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
301 CQ_ITEM *item;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
302 char buf[1];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
303
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
304 if (read(fd, buf, 1) != 1)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
305 if (settings.verbose > 0)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
306 fprintf(stderr, "Can't read from libevent pipe\n");
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
307
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
308 item = cq_peek(&me->new_conn_queue);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
309
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
310 if (NULL != item) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
311 conn *c = conn_new(item->sfd, item->init_state, item->event_flags,
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
312 item->read_buffer_size, item->is_udp, me->base);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
313 if (!c) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
314 if (item->is_udp) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
315 fprintf(stderr, "Can't listen for events on UDP socket\n");
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
316 exit(1);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
317 } else {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
318 if (settings.verbose > 0) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
319 fprintf(stderr, "Can't listen for events on fd %d\n",
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
320 item->sfd);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
321 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
322 close(item->sfd);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
323 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
324 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
325 cqi_free(item);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
326 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
327 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
328
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
329 /* Which thread we assigned a connection to most recently. */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
330 static int last_thread = -1;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
331
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
332 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
333 * Dispatches a new connection to another thread. This is only ever called
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
334 * from the main thread, either during initialization (for UDP) or because
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
335 * of an incoming connection.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
336 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
337 void dispatch_conn_new(int sfd, int init_state, int event_flags,
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
338 int read_buffer_size, int is_udp) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
339 CQ_ITEM *item = cqi_new();
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
340 int thread = (last_thread + 1) % settings.num_threads;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
341
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
342 last_thread = thread;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
343
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
344 item->sfd = sfd;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
345 item->init_state = init_state;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
346 item->event_flags = event_flags;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
347 item->read_buffer_size = read_buffer_size;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
348 item->is_udp = is_udp;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
349
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
350 cq_push(&threads[thread].new_conn_queue, item);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
351 if (write(threads[thread].notify_send_fd, "", 1) != 1) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
352 perror("Writing to thread notify pipe");
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
353 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
354 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
355
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
356 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
357 * Returns true if this is the thread that listens for new TCP connections.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
358 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
359 int mt_is_listen_thread() {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
360 return pthread_self() == threads[0].thread_id;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
361 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
362
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
363 /********************************* ITEM ACCESS *******************************/
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
364
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
365 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
366 * Walks through the list of deletes that have been deferred because the items
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
367 * were locked down at the tmie.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
368 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
369 void mt_run_deferred_deletes() {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
370 pthread_mutex_lock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
371 do_run_deferred_deletes();
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
372 pthread_mutex_unlock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
373 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
374
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
375 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
376 * Allocates a new item.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
377 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
378 item *mt_item_alloc(char *key, size_t nkey, int flags, rel_time_t exptime, int nbytes) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
379 item *it;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
380 pthread_mutex_lock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
381 it = do_item_alloc(key, nkey, flags, exptime, nbytes);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
382 pthread_mutex_unlock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
383 return it;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
384 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
385
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
386 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
387 * Returns an item if it hasn't been marked as expired or deleted,
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
388 * lazy-expiring as needed.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
389 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
390 item *mt_item_get_notedeleted(const char *key, const size_t nkey, bool *delete_locked) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
391 item *it;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
392 pthread_mutex_lock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
393 it = do_item_get_notedeleted(key, nkey, delete_locked);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
394 pthread_mutex_unlock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
395 return it;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
396 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
397
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
398 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
399 * Links an item into the LRU and hashtable.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
400 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
401 int mt_item_link(item *item) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
402 int ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
403
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
404 pthread_mutex_lock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
405 ret = do_item_link(item);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
406 pthread_mutex_unlock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
407 return ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
408 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
409
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
410 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
411 * Decrements the reference count on an item and adds it to the freelist if
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
412 * needed.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
413 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
414 void mt_item_remove(item *item) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
415 pthread_mutex_lock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
416 do_item_remove(item);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
417 pthread_mutex_unlock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
418 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
419
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
420 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
421 * Replaces one item with another in the hashtable.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
422 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
423 int mt_item_replace(item *old, item *new) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
424 int ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
425
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
426 pthread_mutex_lock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
427 ret = do_item_replace(old, new);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
428 pthread_mutex_unlock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
429 return ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
430 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
431
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
432 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
433 * Unlinks an item from the LRU and hashtable.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
434 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
435 void mt_item_unlink(item *item) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
436 pthread_mutex_lock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
437 do_item_unlink(item);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
438 pthread_mutex_unlock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
439 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
440
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
441 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
442 * Moves an item to the back of the LRU queue.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
443 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
444 void mt_item_update(item *item) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
445 pthread_mutex_lock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
446 do_item_update(item);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
447 pthread_mutex_unlock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
448 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
449
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
450 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
451 * Adds an item to the deferred-delete list so it can be reaped later.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
452 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
453 char *mt_defer_delete(item *item, time_t exptime) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
454 char *ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
455
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
456 pthread_mutex_lock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
457 ret = do_defer_delete(item, exptime);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
458 pthread_mutex_unlock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
459 return ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
460 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
461
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
462 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
463 * Does arithmetic on a numeric item value.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
464 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
465 char *mt_add_delta(item *item, int incr, unsigned int delta, char *buf) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
466 char *ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
467
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
468 pthread_mutex_lock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
469 ret = do_add_delta(item, incr, delta, buf);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
470 pthread_mutex_unlock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
471 return ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
472 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
473
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
474 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
475 * Stores an item in the cache (high level, obeys set/add/replace semantics)
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
476 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
477 int mt_store_item(item *item, int comm) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
478 int ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
479
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
480 pthread_mutex_lock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
481 ret = do_store_item(item, comm);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
482 pthread_mutex_unlock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
483 return ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
484 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
485
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
486 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
487 * Flushes expired items after a flush_all call
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
488 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
489 void mt_item_flush_expired() {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
490 pthread_mutex_lock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
491 do_item_flush_expired();
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
492 pthread_mutex_unlock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
493 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
494
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
495 /****************************** HASHTABLE MODULE *****************************/
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
496
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
497 void mt_assoc_move_next_bucket() {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
498 pthread_mutex_lock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
499 do_assoc_move_next_bucket();
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
500 pthread_mutex_unlock(&cache_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
501 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
502
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
503 /******************************* SLAB ALLOCATOR ******************************/
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
504
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
505 void *mt_slabs_alloc(size_t size) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
506 void *ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
507
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
508 pthread_mutex_lock(&slabs_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
509 ret = do_slabs_alloc(size);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
510 pthread_mutex_unlock(&slabs_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
511 return ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
512 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
513
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
514 void mt_slabs_free(void *ptr, size_t size) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
515 pthread_mutex_lock(&slabs_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
516 do_slabs_free(ptr, size);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
517 pthread_mutex_unlock(&slabs_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
518 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
519
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
520 char *mt_slabs_stats(int *buflen) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
521 char *ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
522
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
523 pthread_mutex_lock(&slabs_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
524 ret = do_slabs_stats(buflen);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
525 pthread_mutex_unlock(&slabs_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
526 return ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
527 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
528
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
529 #ifdef ALLOW_SLABS_REASSIGN
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
530 int mt_slabs_reassign(unsigned char srcid, unsigned char dstid) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
531 int ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
532
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
533 pthread_mutex_lock(&slabs_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
534 ret = do_slabs_reassign(srcid, dstid);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
535 pthread_mutex_unlock(&slabs_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
536 return ret;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
537 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
538 #endif
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
539
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
540 /******************************* GLOBAL STATS ******************************/
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
541
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
542 void mt_stats_lock() {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
543 pthread_mutex_lock(&stats_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
544 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
545
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
546 void mt_stats_unlock() {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
547 pthread_mutex_unlock(&stats_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
548 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
549
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
550 /*
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
551 * Initializes the thread subsystem, creating various worker threads.
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
552 *
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
553 * nthreads Number of event handler threads to spawn
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
554 * main_base Event base for main thread
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
555 */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
556 void thread_init(int nthreads, struct event_base *main_base) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
557 int i;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
558
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
559 pthread_mutex_init(&cache_lock, NULL);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
560 pthread_mutex_init(&conn_lock, NULL);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
561 pthread_mutex_init(&slabs_lock, NULL);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
562 pthread_mutex_init(&stats_lock, NULL);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
563
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
564 pthread_mutex_init(&init_lock, NULL);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
565 pthread_cond_init(&init_cond, NULL);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
566
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
567 pthread_mutex_init(&cqi_freelist_lock, NULL);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
568 cqi_freelist = NULL;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
569
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
570 threads = malloc(sizeof(LIBEVENT_THREAD) * nthreads);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
571 if (! threads) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
572 perror("Can't allocate thread descriptors");
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
573 exit(1);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
574 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
575
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
576 threads[0].base = main_base;
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
577 threads[0].thread_id = pthread_self();
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
578
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
579 for (i = 0; i < nthreads; i++) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
580 int fds[2];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
581 if (pipe(fds)) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
582 perror("Can't create notify pipe");
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
583 exit(1);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
584 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
585
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
586 threads[i].notify_receive_fd = fds[0];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
587 threads[i].notify_send_fd = fds[1];
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
588
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
589 setup_thread(&threads[i]);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
590 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
591
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
592 /* Create threads after we've done all the libevent setup. */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
593 for (i = 1; i < nthreads; i++) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
594 create_worker(worker_libevent, &threads[i]);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
595 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
596
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
597 /* Wait for all the threads to set themselves up before returning. */
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
598 pthread_mutex_lock(&init_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
599 init_count++; // main thread
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
600 while (init_count < nthreads) {
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
601 pthread_cond_wait(&init_cond, &init_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
602 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
603 pthread_mutex_unlock(&init_lock);
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
604 }
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
605
30782bb1fc04 memcached-1.2.3
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff changeset
606 #endif