On Sep 14, 2011, at 9:39 PM, Dave Zarzycki wrote:
>
> That's fine. Your block can still get at your object's instance variables:
>
> - (void)doSomething
> {
> x = create_something();
> dispatch_sync(consumer_q, ^{
> _prev_state_ivar = do_something_with(_prev_state_ivar, x);
> });
> // do_something_with() is done
> }
OK, I see how I can "hand off" an object from one thread to another, and wait
in the producer thread until the consumer finished with processing this data. I
suspect, in do_something_with(), the consumer receives a method like
consumeData:.
Still, I don't see how this can work in my scenario. I'm not sure if I was
clear enough how my consumer works and if you took care for this special issu.
So I will try to explain it in more detail:
Unless I miss something, the above consumer has the capability to keep its
complete state after returning from precessing a chunk of at data. It is also
capable to execute its method consumeData: on the same thread where it is
invoked. And as such is capable to return from method "consumeData:" , while
keeping its state, and is also capable to process subsequent chunks of content
through re-entering consumeData:.
So, it can basically do this:
accept data in tread A, process partial data in tread A, and return while
saving its state. Repeat with next partial data.
This, however is not the case with my consumer. This consumer is a "recursive
descent" parser, which keeps its state on the call-stack. It cannot parse
partial content, through a method like parserPartialData: , then return with
result "NEED_MORE_DATA" and later get the next chunk of data.
Usually, a recursive decent parser has a method parse:(NSString*)string, where
a *complete* text shall be passed as the parameter. It must not be partial
text. Then the parser starts parsing on the same thread and returns the result.
Its "parsing state" will be kept on the call stack while it is executing parse:
- not in some member variable or ivar. So it cannot return from parsing a
partial content without saying: "error: unexpected end of data".
So, basically the parser can do this:
result r = parse(someString);
no repeat. no partial content. Once it did parse, parse is finished.
Due to lack of a better solution, I made this work with this kind of parser as
follows:
It is possible to make this kind of parser work with feeding it *partial
content*. This requires:
1) the parser must run in its own thread (see method start and run)
2) the parser accesses and "dereferences" a special "iterator" (see method
next), which points to the content. If a partial buffer is finished, it waits
until a new buffer is offered by a producer. This may block.
3) from another thread, there must be a possibility to feed the parser with
partial content (see method consumeTheThing:)
4) there need to be one actor which helps in handing off the buffers from a
producer thread to the parser's thread. (see synchronous queue).
In one of my previous post, I outlined these basic methods of the parser:
- (void) start; // invoked from a client to run parser asynchronously on its
thread
- (void) run;
- (char) next; // called from the parser internally, will block if no new
buffer has been offered.
- (void) consumeTheThing:(NSData*)partialData // invoked from the producer on
another thread than run is executing.
And internally, the parser uses the "synchronous queue" where objects where
handed off from the producer to the parser.
So, if I possibly missed something here, I would be glad to get enlightened. ;)
Andreas
>
>> The consumer's state (it's a parser) is the function stack. So, I need an
>> intermediate actor - which is capable to hand off one data object. This is
>> some kind of queue.
>
> A dispatch queue should work just fine.
>
> davez
>
>
>>
>>>
>>> A note about dispatch semaphores: While they are powerful, they are not
>>> meant to replace queues. They exist for two very specific problems: 1)
>>> Refactoring synchronous APIs on top of asynchronous APIs and
>>
>>> 2) managing finite resource pools.
>> This (2) is actually what I'm trying to accomplish (well, a bit more -
>> performance for example). Otherwise, I would just safe the 100Mbyte data
>> download on my iPhone in memory ;)
>>
>> A synchronous queue, would have capacity zero -- which would block producers
>> till a consumer takes the data. This is what I want. Otherwise, if I would
>> asynchronously queue the NSData objects, somehow, NSURLConnection would
>> flood a iPhone with almost 1Mbyte per sec, that is a few seconds before
>> crash.
>>
>> So, unless the parser is capable to truly parse partial content, and can
>> return and restart while it's state is kept somewhere else, I can't see how
>> to make it "easy" in conjunction with a NSURLConnection :)
>>
>>
>> So, the questions remains: would the use of a "Synchronous Queue" be
>> effective enough? What are the consequences?
>>
>> Andreas
>>
>>
>> _______________________________________________
>>
>> Cocoa-dev mailing list ([email protected])
>>
>> Please do not post admin requests or moderator comments to the list.
>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>>
>> Help/Unsubscribe/Update your Subscription:
>> http://lists.apple.com/mailman/options/cocoa-dev/zarzycki%40apple.com
>>
>> This email sent to [email protected]
>
_______________________________________________
Cocoa-dev mailing list ([email protected])
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]