2010-12-09 2 views
2

Я выполняю программирование сокетов async, и мой код работает большую часть времени, но иногда это не так. Суть в том, что я создаю пару сокетов, создаю потоки чтения и записи, а затем, когда я хочу что-то написать, я планирую его в цикле выполнения отдельного потока. Как так:CFWriteStreamScheduleWithRunLoop иногда работает, иногда нет?

CFStreamClientContext context = {0, sc, NULL, NULL, NULL}; 
if (CFWriteStreamSetClient(sc.writeStream, kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, myWriteStreamCallBack, &context)) { 
CFWriteStreamScheduleWithRunLoop(sc.writeStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); 
} 

... где myWriteStreamCallback является статической функцией правильной формы ...

сокетов/были открыты потоки, как так:

CFReadStreamRef readStream = NULL; 
CFWriteStreamRef writeStream = NULL; 

@try { 
    // create a pair of streams to the host and open them 

    CFStreamCreatePairWithSocketToCFHost(kCFAllocatorDefault, scomm.host, SERVER_PORT, &readStream, &writeStream); 
    if (readStream == NULL)  @throw [[[CommunicationReadStreamNotCreatedException alloc] init] autorelease]; 
    if (writeStream == NULL) @throw [[[CommunicationWriteStreamNotCreatedException alloc] init] autorelease]; 
    if (!CFReadStreamOpen(readStream)) @throw [[[CommunicationReadStreamNotOpenedException alloc] init] autorelease]; 
    if (!CFWriteStreamOpen(writeStream)) @throw [[[CommunicationWriteStreamNotOpenedException alloc] init] autorelease]; 
    ... 

Теперь к проблеме : этот код (и есть больше, если он поможет кому-либо), в основном правильнее, потому что он в основном работает. Однако иногда, в самом начале программы, я могу попытаться отправить некоторые данные таким образом, и обратный вызов для сокета будет правильно помещен в цикл выполнения, но тогда он никогда не будет вызван. Позже в программе тот же код будет запущен с другим сокетом, и вызов будет вызван (сокеты идут по тому же адресу).

Я знаю, что это расплывчато, но прежде чем я войду в публикацию всего кода, есть ли у кого-нибудь какие-либо грубые идеи о вещах, которые могут потенциально вызвать это? Обратные вызовы иногда не получают вызова на runloops, то есть.

О, да, я должен добавить, что это, очевидно, какой-то тип расы - я могу неустранимо устранить проблему, добавив в записи ведения журнала нужные места. И тогда он иногда работает, а иногда нет, с тем же кодом. Весело весело.

ответ

1

Я получил решение от «Quinn эскимос» на яблоневых форумах:

Проблема была разрешение хозяина сделано в одном потоке и CFHostRef используется в других потоках. Это плохо.

CFHost создание сделано в той же теме (scomm.host объект, выше) исправляет проблему.