@@ -59,6 +59,7 @@ static uintmax_t add_iovec(mustache_api_t *api,
59
59
void * userdata ,
60
60
const char * buffer ,
61
61
uintmax_t buffer_size );
62
+ static void cleanup_fortunes (void * data );
62
63
static int compare_fortunes (const list_t * x , const list_t * y );
63
64
static void complete_fortunes (struct st_h2o_generator_t * self , h2o_req_t * req );
64
65
static list_t * get_sorted_sublist (list_t * head );
@@ -109,6 +110,22 @@ static uintmax_t add_iovec(mustache_api_t *api,
109
110
return ret ;
110
111
}
111
112
113
+ static void cleanup_fortunes (void * data )
114
+ {
115
+ fortune_ctx_t * const fortune_ctx = data ;
116
+ const list_t * iter = fortune_ctx -> result ;
117
+
118
+ if (iter )
119
+ do {
120
+ const fortune_t * const fortune = H2O_STRUCT_FROM_MEMBER (fortune_t , l , iter );
121
+
122
+ if (fortune -> data )
123
+ PQclear (fortune -> data );
124
+
125
+ iter = iter -> next ;
126
+ } while (iter );
127
+ }
128
+
112
129
static int compare_fortunes (const list_t * x , const list_t * y )
113
130
{
114
131
const fortune_t * const f1 = H2O_STRUCT_FROM_MEMBER (fortune_t , l , x );
@@ -142,12 +159,7 @@ static list_t *get_sorted_sublist(list_t *head)
142
159
if (head ) {
143
160
head = head -> next ;
144
161
145
- while (head && compare_fortunes (tail , head ) < 0 ) {
146
- tail = head ;
147
- head = head -> next ;
148
- }
149
-
150
- while (head && !compare_fortunes (tail , head )) {
162
+ while (head && compare_fortunes (tail , head ) <= 0 ) {
151
163
tail = head ;
152
164
head = head -> next ;
153
165
}
@@ -209,40 +221,33 @@ static result_return_t on_fortune_result(db_query_param_t *param, PGresult *resu
209
221
ret = SUCCESS ;
210
222
211
223
for (size_t i = 0 ; i < num_rows ; i ++ ) {
212
- const char * const message_data = PQgetvalue (result , i , 1 );
213
- h2o_iovec_t message = h2o_htmlescape (& fortune_ctx -> req -> pool ,
214
- message_data ,
215
- PQgetlength (result , i , 1 ));
216
- const size_t id_len = PQgetlength (result , i , 0 );
217
- const size_t fortune_size = offsetof(fortune_t , data ) + id_len +
218
- (message_data == message .base ? message .len : 0 );
219
224
fortune_t * const fortune = h2o_mem_alloc_pool (& fortune_ctx -> req -> pool ,
220
- fortune_size );
225
+ sizeof ( * fortune ) );
221
226
222
227
if (fortune ) {
223
- memset (fortune , 0 , offsetof(fortune_t , data ));
224
- memcpy (fortune -> data , PQgetvalue (result , i , 0 ), id_len );
225
- fortune -> id .base = fortune -> data ;
226
- fortune -> id .len = id_len ;
227
-
228
- if (message_data == message .base ) {
229
- message .base = fortune -> data + id_len ;
230
- memcpy (message .base , message_data , message .len );
231
- }
232
-
233
- fortune -> message = message ;
228
+ memset (fortune , 0 , sizeof (* fortune ));
229
+ fortune -> id .base = PQgetvalue (result , i , 0 );
230
+ fortune -> id .len = PQgetlength (result , i , 0 );
231
+ fortune -> message = h2o_htmlescape (& fortune_ctx -> req -> pool ,
232
+ PQgetvalue (result , i , 1 ),
233
+ PQgetlength (result , i , 1 ));
234
234
fortune -> l .next = fortune_ctx -> result ;
235
235
fortune_ctx -> result = & fortune -> l ;
236
236
fortune_ctx -> num_result ++ ;
237
+
238
+ if (!i )
239
+ fortune -> data = result ;
237
240
}
238
241
else {
239
242
send_error (INTERNAL_SERVER_ERROR , MEM_ALLOC_ERR_MSG , fortune_ctx -> req );
240
243
ret = DONE ;
244
+
245
+ if (!i )
246
+ PQclear (result );
247
+
241
248
break ;
242
249
}
243
250
}
244
-
245
- PQclear (result );
246
251
}
247
252
else if (result ) {
248
253
PQclear (result );
@@ -365,7 +370,9 @@ int fortunes(struct st_h2o_handler_t *self, h2o_req_t *req)
365
370
thread_context_t * const ctx = H2O_STRUCT_FROM_MEMBER (thread_context_t ,
366
371
event_loop .h2o_ctx ,
367
372
req -> conn -> ctx );
368
- fortune_ctx_t * const fortune_ctx = h2o_mem_alloc_pool (& req -> pool , sizeof (* fortune_ctx ));
373
+ fortune_ctx_t * const fortune_ctx = h2o_mem_alloc_shared (& req -> pool ,
374
+ sizeof (* fortune_ctx ),
375
+ cleanup_fortunes );
369
376
370
377
if (fortune_ctx ) {
371
378
fortune_t * const fortune = h2o_mem_alloc_pool (& req -> pool , sizeof (* fortune ));
@@ -390,6 +397,8 @@ int fortunes(struct st_h2o_handler_t *self, h2o_req_t *req)
390
397
if (execute_query (ctx , & fortune_ctx -> param ))
391
398
send_service_unavailable_error (DB_REQ_ERROR , req );
392
399
}
400
+ else
401
+ send_error (INTERNAL_SERVER_ERROR , MEM_ALLOC_ERR_MSG , req );
393
402
}
394
403
else
395
404
send_error (INTERNAL_SERVER_ERROR , MEM_ALLOC_ERR_MSG , req );
0 commit comments