Browse Source

H2O: Various changes again (#4931)

* Switch most of the calls to memory allocation routines to
h2o_mem_alloc() - leads to cleaner code.
* Remove the multi-process functionality from the h2o.sh script -
it is no longer necessary.
* Make sure that calls to abort() are preceded by printing an error
message
Anton Kirilov 6 years ago
parent
commit
3edb4c0e08

+ 2 - 16
frameworks/C/h2o/h2o.sh

@@ -8,7 +8,6 @@ H2O_APP_PROFILE_URL="http://127.0.0.1:$H2O_APP_PROFILE_PORT"
 SCRIPT_PATH=$(realpath "$0")
 H2O_APP_SRC_ROOT=$(dirname "$SCRIPT_PATH")
 H2O_APP_BUILD_DIR="${H2O_APP_SRC_ROOT}/build"
-NUM_WORKERS="$CPU_COUNT"
 
 if [[ -z "$DBHOST" ]]; then
 	DBHOST=tfb-database
@@ -29,11 +28,9 @@ fi
 # A hacky way to detect whether we are running in the physical hardware or the cloud environment.
 if [[ "$CPU_COUNT" -gt 16 ]]; then
 	echo "Running h2o_app in the physical hardware environment."
-	USE_PROCESSES=false
 	DB_CONN=3
 else
 	echo "Running h2o_app in the cloud environment."
-	USE_PROCESSES=false
 	DB_CONN=5
 fi
 
@@ -54,6 +51,7 @@ run_curl()
 
 run_h2o_app()
 {
+	LD_LIBRARY_PATH="${MUSTACHE_C_PREFIX}/lib:$LD_LIBRARY_PATH" \
 	taskset -c "$1" "$2/h2o_app" -a20 -f "$3/template" -m "$DB_CONN" "$4" "$5" \
 	        -d "host=$DBHOST dbname=hello_world user=benchmarkdbuser sslmode=disable \
 	            password=benchmarkdbpass" &
@@ -86,17 +84,5 @@ make -j "$CPU_COUNT" install
 popd
 rm -rf "$H2O_APP_BUILD_DIR"
 echo "Maximum database connections per thread: $DB_CONN"
-export LD_LIBRARY_PATH="${MUSTACHE_C_PREFIX}/lib:$LD_LIBRARY_PATH"
-
-if "$USE_PROCESSES"; then
-	echo "h2o_app processes: $NUM_WORKERS"
-
-	for ((i = 0; i < NUM_WORKERS; i++)); do
-		run_h2o_app "$i" "${H2O_APP_PREFIX}/bin" "${H2O_APP_PREFIX}/share/h2o_app" -t1
-	done
-else
-	echo "Running h2o_app multithreaded."
-	run_h2o_app 0 "${H2O_APP_PREFIX}/bin" "${H2O_APP_PREFIX}/share/h2o_app"
-fi
-
+run_h2o_app 0 "${H2O_APP_PREFIX}/bin" "${H2O_APP_PREFIX}/share/h2o_app"
 wait

+ 4 - 11
frameworks/C/h2o/src/database.c

@@ -390,12 +390,8 @@ static void start_database_connect(thread_context_t *ctx, db_conn_t *db_conn)
 	}
 	else {
 		ctx->db_state.db_conn_num++;
-		db_conn = calloc(1, sizeof(*db_conn));
-
-		if (!db_conn) {
-			STANDARD_ERROR("calloc");
-			goto error;
-		}
+		db_conn = h2o_mem_alloc(sizeof(*db_conn));
+		memset(db_conn, 0, sizeof(*db_conn));
 
 		const char * const conninfo = ctx->config->db_host ? ctx->config->db_host : "";
 
@@ -451,17 +447,14 @@ error_dup:
 	PQfinish(db_conn->conn);
 error_connect:
 	free(db_conn);
-error:
 	error_notification(ctx, false, DB_ERROR);
 }
 
 void add_prepared_statement(const char *name, const char *query, list_t **prepared_statements)
 {
-	prepared_statement_t * const p = calloc(1, sizeof(*p));
-
-	if (!p)
-		abort();
+	prepared_statement_t * const p = h2o_mem_alloc(sizeof(*p));
 
+	memset(p, 0, sizeof(*p));
 	p->l.next = *prepared_statements;
 	p->name = name;
 	p->query = query;

+ 2 - 4
frameworks/C/h2o/src/event_loop.c

@@ -233,11 +233,9 @@ static void shutdown_server(h2o_socket_t *listener, const char *err)
 		}
 
 		for (size_t i = ctx->config->thread_num - 1; i > 0; i--) {
-			message_t * const msg = calloc(1, sizeof(*msg));
-
-			if (!msg)
-				abort();
+			message_t * const msg = h2o_mem_alloc(sizeof(*msg));
 
+			memset(msg, 0, sizeof(*msg));
 			msg->type = SHUTDOWN;
 			h2o_multithread_send_message(&ctx->global_thread_data[i].h2o_receiver, &msg->super);
 		}

+ 24 - 28
frameworks/C/h2o/src/handlers/fortune.c

@@ -194,35 +194,31 @@ static int fortunes(struct st_h2o_handler_t *self, h2o_req_t *req)
 	thread_context_t * const ctx = H2O_STRUCT_FROM_MEMBER(thread_context_t,
 	                                                      event_loop.h2o_ctx,
 	                                                      req->conn->ctx);
-	fortune_ctx_t * const fortune_ctx = calloc(1, sizeof(*fortune_ctx));
-
-	if (fortune_ctx) {
-		fortune_t * const fortune = h2o_mem_alloc_pool(&req->pool, sizeof(*fortune));
-		fortune_ctx_t ** const p = h2o_mem_alloc_shared(&req->pool, sizeof(*p), cleanup_request);
-
-		*p = fortune_ctx;
-		memset(fortune, 0, sizeof(*fortune));
-		fortune->id.base = NEW_FORTUNE_ID;
-		fortune->id.len = sizeof(NEW_FORTUNE_ID) - 1;
-		fortune->message.base = NEW_FORTUNE_MESSAGE;
-		fortune->message.len = sizeof(NEW_FORTUNE_MESSAGE) - 1;
-		fortune_ctx->generator.proceed = complete_fortunes;
-		fortune_ctx->num_result = 1;
-		fortune_ctx->param.command = FORTUNE_TABLE_NAME;
-		fortune_ctx->param.on_error = on_fortune_error;
-		fortune_ctx->param.on_result = on_fortune_result;
-		fortune_ctx->param.on_timeout = on_fortune_timeout;
-		fortune_ctx->param.flags = IS_PREPARED;
-		fortune_ctx->req = req;
-		fortune_ctx->result = &fortune->l;
-
-		if (execute_query(ctx, &fortune_ctx->param)) {
-			fortune_ctx->cleanup = true;
-			send_service_unavailable_error(DB_REQ_ERROR, req);
-		}
+	fortune_ctx_t * const fortune_ctx = h2o_mem_alloc(sizeof(*fortune_ctx));
+	fortune_t * const fortune = h2o_mem_alloc_pool(&req->pool, sizeof(*fortune));
+	fortune_ctx_t ** const p = h2o_mem_alloc_shared(&req->pool, sizeof(*p), cleanup_request);
+
+	*p = fortune_ctx;
+	memset(fortune, 0, sizeof(*fortune));
+	fortune->id.base = NEW_FORTUNE_ID;
+	fortune->id.len = sizeof(NEW_FORTUNE_ID) - 1;
+	fortune->message.base = NEW_FORTUNE_MESSAGE;
+	fortune->message.len = sizeof(NEW_FORTUNE_MESSAGE) - 1;
+	memset(fortune_ctx, 0, sizeof(*fortune_ctx));
+	fortune_ctx->generator.proceed = complete_fortunes;
+	fortune_ctx->num_result = 1;
+	fortune_ctx->param.command = FORTUNE_TABLE_NAME;
+	fortune_ctx->param.on_error = on_fortune_error;
+	fortune_ctx->param.on_result = on_fortune_result;
+	fortune_ctx->param.on_timeout = on_fortune_timeout;
+	fortune_ctx->param.flags = IS_PREPARED;
+	fortune_ctx->req = req;
+	fortune_ctx->result = &fortune->l;
+
+	if (execute_query(ctx, &fortune_ctx->param)) {
+		fortune_ctx->cleanup = true;
+		send_service_unavailable_error(DB_REQ_ERROR, req);
 	}
-	else
-		send_error(INTERNAL_SERVER_ERROR, REQ_ERROR, req);
 
 	return 0;
 }

+ 111 - 122
frameworks/C/h2o/src/handlers/world.c

@@ -250,67 +250,65 @@ static int do_multiple_queries(bool do_update, bool use_cache, h2o_req_t *req)
 			sz += update_query_len - reuse_size;
 	}
 
-	multiple_query_ctx_t * const query_ctx = calloc(1, sz);
-
-	if (query_ctx) {
-		multiple_query_ctx_t ** const p = h2o_mem_alloc_shared(&req->pool,
-		                                                       sizeof(*p),
-		                                                       cleanup_multiple_query_request);
-
-		*p = query_ctx;
-		query_ctx->ctx = ctx;
-		query_ctx->num_query = num_query;
-		query_ctx->req = req;
-		query_ctx->query_param = (query_param_t *) ((char *) query_ctx + base_size);
-		initialize_ids(num_query, query_ctx->res, &ctx->random_seed);
-
-		if (do_update)
-			query_ctx->flags |= DO_UPDATE;
-
-		if (use_cache) {
-			query_ctx->flags |= USE_CACHE;
-			fetch_from_cache(h2o_now(ctx->event_loop.h2o_ctx.loop),
-			                 &ctx->global_data->request_handler_data.world_cache,
-			                 query_ctx);
-
-			if (query_ctx->num_result == query_ctx->num_query) {
-				complete_multiple_query(query_ctx);
-				return 0;
-			}
+	multiple_query_ctx_t * const query_ctx = h2o_mem_alloc(sz);
+	multiple_query_ctx_t ** const p = h2o_mem_alloc_shared(&req->pool,
+	                                                       sizeof(*p),
+	                                                       cleanup_multiple_query_request);
+
+	*p = query_ctx;
+	memset(query_ctx, 0, sz);
+	query_ctx->ctx = ctx;
+	query_ctx->num_query = num_query;
+	query_ctx->req = req;
+	query_ctx->query_param = (query_param_t *) ((char *) query_ctx + base_size);
+	initialize_ids(num_query, query_ctx->res, &ctx->random_seed);
+
+	if (do_update)
+		query_ctx->flags |= DO_UPDATE;
+
+	if (use_cache) {
+		query_ctx->flags |= USE_CACHE;
+		fetch_from_cache(h2o_now(ctx->event_loop.h2o_ctx.loop),
+		                 &ctx->global_data->request_handler_data.world_cache,
+		                 query_ctx);
+
+		if (query_ctx->num_result == query_ctx->num_query) {
+			complete_multiple_query(query_ctx);
+			return 0;
 		}
+	}
 
-		query_ctx->num_query_in_progress = MIN(num_query_in_progress,
-		                                       query_ctx->num_query - query_ctx->num_result);
-
-		for (size_t i = 0; i < query_ctx->num_query_in_progress; i++) {
-			query_ctx->query_param[i].ctx = query_ctx;
-			// We need a copy of id because the original may be overwritten
-			// by a completed query.
-			query_ctx->query_param[i].id = htonl(query_ctx->res[query_ctx->num_result + i].id);
-			query_ctx->query_param[i].id_format = 1;
-			query_ctx->query_param[i].id_len = sizeof(query_ctx->query_param[i].id);
-			query_ctx->query_param[i].id_pointer = (const char *) &query_ctx->query_param[i].id;
-			query_ctx->query_param[i].param.command = WORLD_TABLE_NAME;
-			query_ctx->query_param[i].param.nParams = 1;
-			query_ctx->query_param[i].param.on_error = on_multiple_query_error;
-			query_ctx->query_param[i].param.on_result = on_multiple_query_result;
-			query_ctx->query_param[i].param.on_timeout = on_multiple_query_timeout;
-			query_ctx->query_param[i].param.paramFormats = &query_ctx->query_param[i].id_format;
-			query_ctx->query_param[i].param.paramLengths = &query_ctx->query_param[i].id_len;
-			query_ctx->query_param[i].param.paramValues = &query_ctx->query_param[i].id_pointer;
-			query_ctx->query_param[i].param.flags = IS_PREPARED;
-			query_ctx->query_param[i].param.resultFormat = 1;
-
-			if (execute_query(ctx, &query_ctx->query_param[i].param)) {
-				query_ctx->num_query_in_progress = i;
-				query_ctx->flags |= DO_CLEANUP;
-				send_service_unavailable_error(DB_REQ_ERROR, req);
-				return 0;
-			}
-		}
+	query_ctx->num_query_in_progress = MIN(num_query_in_progress,
+	                                       query_ctx->num_query - query_ctx->num_result);
+
+	// Keep this loop separate, so that it could be vectorized.
+	for (size_t i = 0; i < query_ctx->num_query_in_progress; i++) {
+		query_ctx->query_param[i].ctx = query_ctx;
+		// We need a copy of id because the original may be overwritten
+		// by a completed query.
+		query_ctx->query_param[i].id = htonl(query_ctx->res[query_ctx->num_result + i].id);
+		query_ctx->query_param[i].id_format = 1;
+		query_ctx->query_param[i].id_len = sizeof(query_ctx->query_param[i].id);
+		query_ctx->query_param[i].id_pointer = (const char *) &query_ctx->query_param[i].id;
+		query_ctx->query_param[i].param.command = WORLD_TABLE_NAME;
+		query_ctx->query_param[i].param.nParams = 1;
+		query_ctx->query_param[i].param.on_error = on_multiple_query_error;
+		query_ctx->query_param[i].param.on_result = on_multiple_query_result;
+		query_ctx->query_param[i].param.on_timeout = on_multiple_query_timeout;
+		query_ctx->query_param[i].param.paramFormats = &query_ctx->query_param[i].id_format;
+		query_ctx->query_param[i].param.paramLengths = &query_ctx->query_param[i].id_len;
+		query_ctx->query_param[i].param.paramValues = &query_ctx->query_param[i].id_pointer;
+		query_ctx->query_param[i].param.flags = IS_PREPARED;
+		query_ctx->query_param[i].param.resultFormat = 1;
 	}
-	else
-		send_error(INTERNAL_SERVER_ERROR, REQ_ERROR, req);
+
+	for (size_t i = 0; i < query_ctx->num_query_in_progress; i++)
+		if (execute_query(ctx, &query_ctx->query_param[i].param)) {
+			query_ctx->num_query_in_progress = i;
+			query_ctx->flags |= DO_CLEANUP;
+			send_service_unavailable_error(DB_REQ_ERROR, req);
+			break;
+		}
 
 	return 0;
 }
@@ -482,19 +480,16 @@ static result_return_t on_multiple_query_result(db_query_param_t *param, PGresul
 		process_result(result, 0, query_ctx->res + query_ctx->num_result);
 
 		if (query_ctx->flags & USE_CACHE) {
-			query_result_t * const r = malloc(sizeof(*r));
-
-			if (r) {
-				const h2o_iovec_t key = {.base = (char *) &r->id, .len = sizeof(r->id)};
-				const h2o_iovec_t value = {.base = (char *) r, .len = sizeof(*r)};
-
-				*r = query_ctx->res[query_ctx->num_result];
-				cache_set(h2o_now(query_ctx->ctx->event_loop.h2o_ctx.loop),
-				          key,
-				          0,
-				          value,
-				          &query_ctx->ctx->global_data->request_handler_data.world_cache);
-			}
+			query_result_t * const r = h2o_mem_alloc(sizeof(*r));
+			const h2o_iovec_t key = {.base = (char *) &r->id, .len = sizeof(r->id)};
+			const h2o_iovec_t value = {.base = (char *) r, .len = sizeof(*r)};
+
+			*r = query_ctx->res[query_ctx->num_result];
+			cache_set(h2o_now(query_ctx->ctx->event_loop.h2o_ctx.loop),
+			          key,
+			          0,
+			          value,
+			          &query_ctx->ctx->global_data->request_handler_data.world_cache);
 		}
 
 		query_ctx->num_result++;
@@ -559,20 +554,19 @@ static result_return_t on_populate_cache_result(db_query_param_t *param, PGresul
 		const size_t num_rows = PQntuples(result);
 
 		for (size_t i = 0; i < num_rows; i++) {
-			query_result_t * const r = calloc(1, sizeof(*r));
+			query_result_t * const r = h2o_mem_alloc(sizeof(*r));
 
-			if (r) {
-				process_result(result, i, r);
+			memset(r, 0, sizeof(*r));
+			process_result(result, i, r);
 
-				const h2o_iovec_t key = {.base = (char *) &r->id, .len = sizeof(r->id)};
-				const h2o_iovec_t value = {.base = (char *) r, .len = sizeof(*r)};
+			const h2o_iovec_t key = {.base = (char *) &r->id, .len = sizeof(r->id)};
+			const h2o_iovec_t value = {.base = (char *) r, .len = sizeof(*r)};
 
-				cache_set(h2o_now(query_ctx->ctx->event_loop.h2o_ctx.loop),
-				          key,
-				          0,
-				          value,
-				          &query_ctx->ctx->global_data->request_handler_data.world_cache);
-			}
+			cache_set(h2o_now(query_ctx->ctx->event_loop.h2o_ctx.loop),
+			          key,
+			          0,
+			          value,
+			          &query_ctx->ctx->global_data->request_handler_data.world_cache);
 		}
 	}
 	else
@@ -696,18 +690,17 @@ static void populate_cache(thread_context_t *ctx, void *arg)
 {
 	IGNORE_FUNCTION_PARAMETER(arg);
 
-	populate_cache_ctx_t * const query_ctx = calloc(1, sizeof(*query_ctx));
+	populate_cache_ctx_t * const query_ctx = h2o_mem_alloc(sizeof(*query_ctx));
 
-	if (query_ctx) {
-		query_ctx->ctx = ctx;
-		query_ctx->param.command = POPULATE_CACHE_QUERY;
-		query_ctx->param.on_error = on_populate_cache_error;
-		query_ctx->param.on_result = on_populate_cache_result;
-		query_ctx->param.on_timeout = on_populate_cache_timeout;
+	memset(query_ctx, 0, sizeof(*query_ctx));
+	query_ctx->ctx = ctx;
+	query_ctx->param.command = POPULATE_CACHE_QUERY;
+	query_ctx->param.on_error = on_populate_cache_error;
+	query_ctx->param.on_result = on_populate_cache_result;
+	query_ctx->param.on_timeout = on_populate_cache_timeout;
 
-		if (execute_query(ctx, &query_ctx->param))
-			free(query_ctx);
-	}
+	if (execute_query(ctx, &query_ctx->param))
+		free(query_ctx);
 }
 
 static void process_result(PGresult *result, size_t idx, query_result_t *out)
@@ -791,37 +784,33 @@ static int single_query(struct st_h2o_handler_t *self, h2o_req_t *req)
 	thread_context_t * const ctx = H2O_STRUCT_FROM_MEMBER(thread_context_t,
 	                                                      event_loop.h2o_ctx,
 	                                                      req->conn->ctx);
-	single_query_ctx_t * const query_ctx = calloc(1, sizeof(*query_ctx));
-
-	if (query_ctx) {
-		single_query_ctx_t ** const p = h2o_mem_alloc_shared(&req->pool,
-		                                                     sizeof(*p),
-		                                                     cleanup_single_query_request);
-
-		*p = query_ctx;
-		query_ctx->id = htonl(get_random_number(MAX_ID, &ctx->random_seed) + 1);
-		query_ctx->id_format = 1;
-		query_ctx->id_len = sizeof(query_ctx->id);
-		query_ctx->id_pointer = (const char *) &query_ctx->id;
-		query_ctx->param.command = WORLD_TABLE_NAME;
-		query_ctx->param.nParams = 1;
-		query_ctx->param.on_error = on_single_query_error;
-		query_ctx->param.on_result = on_single_query_result;
-		query_ctx->param.on_timeout = on_single_query_timeout;
-		query_ctx->param.paramFormats = &query_ctx->id_format;
-		query_ctx->param.paramLengths = &query_ctx->id_len;
-		query_ctx->param.paramValues = &query_ctx->id_pointer;
-		query_ctx->param.flags = IS_PREPARED;
-		query_ctx->param.resultFormat = 1;
-		query_ctx->req = req;
-
-		if (execute_query(ctx, &query_ctx->param)) {
-			query_ctx->cleanup = true;
-			send_service_unavailable_error(DB_REQ_ERROR, req);
-		}
+	single_query_ctx_t * const query_ctx = h2o_mem_alloc(sizeof(*query_ctx));
+	single_query_ctx_t ** const p = h2o_mem_alloc_shared(&req->pool,
+	                                                     sizeof(*p),
+	                                                     cleanup_single_query_request);
+
+	*p = query_ctx;
+	memset(query_ctx, 0, sizeof(*query_ctx));
+	query_ctx->id = htonl(get_random_number(MAX_ID, &ctx->random_seed) + 1);
+	query_ctx->id_format = 1;
+	query_ctx->id_len = sizeof(query_ctx->id);
+	query_ctx->id_pointer = (const char *) &query_ctx->id;
+	query_ctx->param.command = WORLD_TABLE_NAME;
+	query_ctx->param.nParams = 1;
+	query_ctx->param.on_error = on_single_query_error;
+	query_ctx->param.on_result = on_single_query_result;
+	query_ctx->param.on_timeout = on_single_query_timeout;
+	query_ctx->param.paramFormats = &query_ctx->id_format;
+	query_ctx->param.paramLengths = &query_ctx->id_len;
+	query_ctx->param.paramValues = &query_ctx->id_pointer;
+	query_ctx->param.flags = IS_PREPARED;
+	query_ctx->param.resultFormat = 1;
+	query_ctx->req = req;
+
+	if (execute_query(ctx, &query_ctx->param)) {
+		query_ctx->cleanup = true;
+		send_service_unavailable_error(DB_REQ_ERROR, req);
 	}
-	else
-		send_error(INTERNAL_SERVER_ERROR, REQ_ERROR, req);
 
 	return 0;
 }

+ 2 - 4
frameworks/C/h2o/src/main.c

@@ -276,11 +276,9 @@ void add_postinitialization_task(void (*task)(struct thread_context_t *, void *)
                                  void *arg,
                                  list_t **postinitialization_tasks)
 {
-	task_t * const t = calloc(1, sizeof(*t));
-
-	if (!t)
-		abort();
+	task_t * const t = h2o_mem_alloc(sizeof(*t));
 
+	memset(t, 0, sizeof(*t));
 	t->l.next = *postinitialization_tasks;
 	t->arg = arg;
 	t->task = task;

+ 5 - 1
frameworks/C/h2o/src/thread.c

@@ -123,6 +123,8 @@ global_thread_data_t *initialize_global_thread_data(const config_t *config,
 			ret[i].global_data = global_data;
 		}
 	}
+	else
+		STANDARD_ERROR("aligned_alloc");
 
 	return ret;
 }
@@ -152,8 +154,10 @@ void start_threads(global_thread_data_t *global_thread_data)
 	const size_t cpusetsize = CPU_ALLOC_SIZE(num_cpus);
 	cpu_set_t * const cpuset = CPU_ALLOC(num_cpus);
 
-	if (!cpuset)
+	if (!cpuset) {
+		STANDARD_ERROR("CPU_ALLOC");
 		abort();
+	}
 
 	CHECK_ERROR(pthread_attr_init, &attr);
 	// The first thread context is used by the main thread.

+ 5 - 2
frameworks/C/h2o/src/tls.c

@@ -150,8 +150,11 @@ void initialize_openssl(const config_t *config, global_data_t *global_data)
 	SSL_library_init();
 	SSL_load_error_strings();
 	openssl_global_data.num_lock = CRYPTO_num_locks();
-	openssl_global_data.lock = calloc(openssl_global_data.num_lock,
-	                                  sizeof(*openssl_global_data.lock));
+	openssl_global_data.lock =
+			h2o_mem_alloc(openssl_global_data.num_lock * sizeof(*openssl_global_data.lock));
+	memset(openssl_global_data.lock,
+	       0,
+	       openssl_global_data.num_lock * sizeof(*openssl_global_data.lock));
 	CHECK_ERROR(pthread_mutexattr_init, &openssl_global_data.lock_attr);
 	CHECK_ERROR(pthread_mutexattr_settype,
 	            &openssl_global_data.lock_attr,

+ 6 - 8
frameworks/C/h2o/src/utility.c

@@ -164,15 +164,13 @@ json_generator_t *get_json_generator(list_t **pool, size_t *gen_num)
 		(*gen_num)--;
 	}
 	else {
-		ret = malloc(sizeof(*ret));
+		ret = h2o_mem_alloc(sizeof(*ret));
+		memset(ret, 0, sizeof(*ret));
+		ret->gen = yajl_gen_alloc(NULL);
 
-		if (ret) {
-			ret->gen = yajl_gen_alloc(NULL);
-
-			if (!ret->gen) {
-				free(ret);
-				ret = NULL;
-			}
+		if (!ret->gen) {
+			free(ret);
+			ret = NULL;
 		}
 	}