1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 
3 /**
4  * @copyright 2014 Couchbase, Inc.
5  *
6  * @author Sarath Lakshman  <sarath@couchbase.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
9  * use this file except in compliance with the License. You may obtain a copy of
10  * the License at
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17  * License for the specific language governing permissions and limitations under
18  * the License.
19  **/
20 
21 #include "config.h"
22 #include "util.h"
23 #include <string.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include "../mapreduce/mapreduce.h"
27 
do_exit(int ret, int uses_v8)28 static void do_exit(int ret, int uses_v8)
29 {
30     /* Notify and delete conditional variables,
31     and join waiting threads when v8 is used */
32     if(uses_v8) {
33         deinit_terminator_thread(true /*fatal_exit*/);
34     }
35     _exit(ret);
36 }
37 
exit_thread_helper(void *args)38 static void exit_thread_helper(void *args)
39 {
40     char buf[4];
41     int len = fread(buf, 1, 4, stdin);
42 
43     int uses_v8 = *reinterpret_cast<int*>(args);
44 
45     /* If the other end closed the pipe */
46     if (len == 0) {
47         do_exit(1, uses_v8);
48     } else if (len == 4 && !strncmp(buf, "exit", 4)) {
49         do_exit(1, uses_v8);
50     } else {
51         fprintf(stderr, "Error occured waiting for exit message (%d)\n", len);
52         do_exit(2, uses_v8);
53     }
54 }
55 
56 /* Start a watcher thread to gracefully die on exit message */
start_exit_listener(cb_thread_t *id, int uses_v8)57 int start_exit_listener(cb_thread_t *id, int uses_v8)
58 {
59     void *args = reinterpret_cast<void*>(&uses_v8);
60     int ret = cb_create_thread(id, exit_thread_helper, args, 1);
61     if (ret < 0) {
62         /* For differentiating from couchstore_error_t */
63         return -ret;
64     }
65 
66     return ret;
67 }
68 
set_binary_mode()69 int set_binary_mode()
70 {
71     if (platform_set_binary_mode(stdin) < 0 ||
72             platform_set_binary_mode(stdout) < 0 ||
73             platform_set_binary_mode(stderr) < 0) {
74         return -1;
75     }
76     return 0;
77 }
78