2015-08-20 2 views
1

Мое приложение копирует файлы с использованием методов dispatch_io_read() и dispatch_io_write(), предоставленных компанией Grand Central Dispatch от Apple OSX 10.10.Когда безопасно вызывать dispatch_io_close() при использовании Grand Central Dispatch?

Я предоставляю своим пользователям кнопку «отменить». Я реализовал это различными способами, используя dispatch_io_close(channel, DISPATCH_IO_STOP), но каждый метод, который я пробовал, приводит к случайным сбоям с сообщениями, такими как «BUG IN LIBDISPATCH: Over-release объекта», «BUG IN LIBDISPATCH: Resurrection of a object» или аналогичный аварии, связанной с проблемами сохранения/выпуска.

я получаю один и тот же тип аварии, если я просто close() файловых дескрипторов файлов я чтение/записи, когда пользователь попадет «отмена», или если я позвоню dispatch_io_close(channel, DISPATCH_IO_STOP) изнутри очистки обработчиков dispatch_io_read() и dispatch_io_write().

Как безопасно отменить операции ввода-вывода GCD?

+0

Невозможно ответить на ваш вопрос, не видя существующего кода. –

ответ

0

Вот пример того, как вы могли бы написать простую замену cat с помощью отправки Io:

#include <dispatch/dispatch.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int main() { 
    dispatch_io_t stdin_io = dispatch_io_create(DISPATCH_IO_STREAM, STDIN_FILENO, dispatch_get_main_queue(), ^(int error) { 
     fprintf(stderr, "Error opening stdin: %d\n", error); 
     exit(error); 
    }); 

    dispatch_io_t stdout_io = dispatch_io_create(DISPATCH_IO_STREAM, STDOUT_FILENO, dispatch_get_main_queue(), ^(int error) { 
     fprintf(stderr, "Error opening stdout: %d\n", error); 
     exit(error); 
    }); 

    dispatch_group_t io_completion_group = dispatch_group_create(); 

    dispatch_group_enter(io_completion_group); 
    dispatch_io_read(stdin_io, 0, SIZE_MAX, dispatch_get_main_queue(), ^(bool done, dispatch_data_t data, int error) { 
     if (error) { 
      fprintf(stderr, "Read error: %d\n", error); 
      exit(error); 
     } 

     dispatch_group_enter(io_completion_group); 
     dispatch_io_write(stdout_io, 0, data, dispatch_get_main_queue(), ^(bool done, dispatch_data_t data, int error) { 
      if (error) { 
       fprintf(stderr, "Write error: %d\n", error); 
       exit(error); 
      } 

      if (done) { 
       dispatch_group_leave(io_completion_group); 
      } 
     }); 

     if (done) { 
      dispatch_group_leave(io_completion_group); 
     } 
    }); 

    dispatch_group_notify(io_completion_group, dispatch_get_main_queue(), ^{ 
     dispatch_io_close(stdin_io, 0); 
     dispatch_release(stdin_io); 

     dispatch_io_close(stdout_io, 0); 
     dispatch_release(stdout_io); 

     dispatch_release(io_completion_group); 

     exit(0); 
    }); 

    dispatch_main(); 
} 

Надеется, что может служить в качестве отправной точки для вас.

Смежные вопросы