libuv безуспешно пытается сделать простой регистратор libuv

попробуйте создать регистратор изнутри сервера libuv (простой), следуя примерам, которые я едва нашел в сети, мне удается писать в файл, но когда я пытаюсь записать в журнал из другого места в коде, я получаю исключение.
вот что у меня есть:

const char* logfile = "wsserver.log";
char buf[] = "Server Started!\n";
uv_fs_t open_req;
uv_fs_t write_req;
uv_fs_t close_req;


int resultFD;


void open_cb(uv_fs_t* req);
void write_cb(uv_fs_t* req);
void close_cb(uv_fs_t* req);


void open_cb(uv_fs_t* req) {
 resultFD = req->result;
 const uv_buf_t buf1 = uv_buf_init(&buf, sizeof(buf));
 if (resultFD == -1) {
 fprintf(stderr, "Error opening file: %s.\n",
 uv_strerror(resultFD));
 }


 uv_fs_req_cleanup(req);
 uv_fs_write(loop, &write_req, resultFD, &buf1, sizeof(buf1), -1, write_cb);
}


void write_cb(uv_fs_t* req) {
 int result = req->result;


 if (result == -1) {
 fprintf(stderr, "Error writting data to file: %s.\n",
 uv_strerror(result));
 }


 uv_fs_req_cleanup(req);
 uv_fs_close(loop, &close_req, open_req.result, close_cb);
}


void close_cb(uv_fs_t* req) {
 int result = req->result;


 if (result == -1) {
 fprintf(stderr, "Error closing file: %s.\n",
 uv_strerror(result));
 }


 uv_fs_req_cleanup(req);

}


int main(int argc, char** argv)
{
 int port = 8011;
 loop = uv_default_loop();
 if (server_start(port))
 {

 return 1;
 }
 int r = uv_fs_open(loop, &open_req, logfile, O_CREAT | O_APPEND, 0644, open_cb);


 if (r) {
 fprintf(stderr, "Error opening file: %s.\n",
 uv_strerror(r));
 }

 uv_run(loop, UV_RUN_DEFAULT);
 return 0;
}

Этот код работает, он создает файл и добавляет строку «Server Started!\n». но проблема в том, что когда я пытаюсь записать в файл из другого места в коде, например:
где я пытаюсь распечатать буфер HTTP-запроса, получая исключение в

libuv_httpparser_ws.exe!uv__get_osfhandle(int fd) Строка 174 C в файле: handle-inl.h

void after_read(uv_stream_t* handle, ssize_t nread, const uv_buf_t * buf) {
 if (nread < 0) {

 if (buf->base) {
 free(buf->base);
 } 
 uv_close((uv_handle_t*)handle, on_close);
 return;
 }
 if (nread == 0) {
 free(buf->base);
 return;
 }

 _context* ctx = handle->data;

 if (ctx->request->handshake == 0) {
 //here you getting the request from the client 

 printf("buf->base %s\n", buf->base);
 uv_fs_write(loop, &write_req, resultFD, buf->base, sizeof(buf->base), -1, write_cb); //<---HERE I TRY TO WRITE TO THE FILE WITHOUT SUCCESS
 size_t np = http_parser_execute(ctx->parser, &settings, buf->base, nread);

 int _http_errno =ctx->parser->http_errno;
 const char * _errno = http_errno_description((enum http_errno)_http_errno);
 int _upgrade = ctx->parser->upgrade;

 free(buf->base);
 if (np != nread) {
 uv_shutdown_t* req;
 req = (uv_shutdown_t*)malloc(sizeof *req);
 uv_shutdown(req, handle, after_shutdown);
 }
 }
}

что я делаю не так и как сделать правильный простой регистратор? Спасибо


person user63898    schedule 23.05.2016    source источник


Ответы (1)


Вы освобождаете buf->base после вызова uv_fs_write, но uv_fs_write не будет копировать содержимое буфера, поэтому память должна оставаться действительной до тех пор, пока не будет вызван обратный вызов записи.

Я бы посоветовал вам использовать блокировку записи для ведения журнала, пока это не станет проблемой. Затем, возможно, переключитесь на использование UDP для ведения журнала на удаленный сервер.

person saghul    schedule 18.06.2016