<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>On Sep 8, 2010, at 8:42 PM, cee1 wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>Questions:</div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>1. How does a source's event handler accesses data returned by kevent?</div>
<div><br></div><div>Data returned by kevent will finally be recorded is ds_data field in _dispatch_source_latch_and_call. The event handler will be called with ds_handler_ctxt, which shoule be do_ctxt. "do_ctxt" can be set by function dispatch_set_context. The problem is:</div>
<div><ul><li>If a handler need to access ds_data, we have to set a proper do_ctxt (e.g. a do_ctxt of source). That's not convenient.</li></ul></div></blockquote></blockquote>It is only inconvenient if you're in the prototyping stage of a project. By the time a project matures, there will surely be a data structure that tracks a connection, and as a part of that connection, a pointer back to the dispatch_source_t. For example:</div><div><br></div><div>struct my_connection_s {</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>...</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>dispatch_source_t source;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>...</div><div>};</div><div><br></div><div>...</div><div><br></div><div>void my_connection_handler(void *ctxt)</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>struct my_connection_s *mc = ctxt;</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>printf("new data: %lu\n", dispatch_source_get_data(mc->source));</div><div>}</div><div><br></div><div>...</div><div><br></div><div>struct my_connection_s *mc = my_connection_create();</div><div><br></div><div>mc->source = dispatch_source_create(...);</div><div><br></div><div>dispatch_set_context(mc->source, mc);</div><div>dispatch_source_set_event_handler_f(mc->source, my_connection_handler);</div><div>dispatch_resume(mc->source);</div><div><br></div><div>...</div><div><br></div><div><br></div><div><blockquote type="cite"><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><ul><li>"ds_data" is a member of dispatch_source_t, and dispatch_source_t is an opaque struct to client code.</li></ul></div></blockquote></blockquote><div>See the example above where dispatch_source_get_data() is used.</div></div><div><br><blockquote type="cite"><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><ul>
</ul></div></blockquote><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>2. We have custom source of type DISPATCH_SOURCE_TYPE_DATA_ADD and DISPATCH_SOURCE_TYPE_DATA_OR, and can use dispatch_source_merge_data</div>
<div>to fire custom sources. Why we don't have an 'is_level' source?</div></blockquote></blockquote></div><div><blockquote type="cite"><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>An "is_level" source may not make much sense, but can be attached with cancel handler, this may be useful in some cases.</div></blockquote></blockquote><div><br></div><div>If you can think of a practical use for that, then let us know.</div><div><br></div><div>davez</div></div></body></html>