On Tue, 20 Mar 2018 10:06:43 -0300 Gustavo Sverzut Barbieri
<barbi...@gmail.com> said:

> >  static void
> >  _exe_exit_eval(Eo *obj, Efl_Exe_Data *pd)
> >  {
> >     if ((pd->fd.out == -1) && /*(pd->fd.in == -1) &&*/
> >         (pd->fd.exited_read == -1) && (!pd->exit_called))
> >       {
> > -        Eina_Future *job;
> > -        Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS);
> > -
> >          pd->exit_called = EINA_TRUE;
> > -        efl_ref(obj);
> > -        job = eina_future_then(efl_loop_job(loop), _efl_loop_task_exit,
> > obj);
> > -        efl_future_Eina_FutureXXX_then(obj, job);
> > +        if (pd->promise)
> > +          {
> > +             int exit_code = efl_task_exit_code_get(obj);
> > +             if (exit_code != 0) eina_promise_reject(pd->promise,
> > exit_code + 1000000);
> > +             else eina_promise_resolve(pd->promise,
> > eina_value_int_init(0));
> 
> I said I'd give up... but seeing this makes me sad.
> 
> in two lines you: misused the Eina_Error AND missed the purpose of resolve.
> 
> I hoped when you looked at it, written as code, you'd realize the
> mistake... but seems not... so I'm pointing here.
> 
> eina_error conversion to string (which will be helpful to high level
> languages) is missed, "+ 1000000" is an error that is not
> registered...
> 
> OTOH success is always ZERO, so there is no value... IF that would be
> right, then it should be a void promise (carries no value).
> 
> but my hope is that you'll simply move this to
> eina_promise_resolve(pd->promise, eina_value_int_init(exit_code))
> 
> and listen to my advice that is to move the "!= 0" *OUTSIDE* of this
> function, you're mixing roles :-/

eh? we only have 1 value to know of success or failure. an int. 0 == success.
anything else is failure. that's precisely what i did right there.

take a look at efl_io_manager.c ... go on. this is EXACTLY[ what it does too.
the same examples of using promises tat you want me to look at do exactly this.
just look at _file_stat_done_cb()

it does exactly the same thing:

static void
_file_stat_done_cb(void *data, Eio_File *handle EINA_UNUSED, const Eina_Stat
*st) {
   const Eina_Value_Struct value = { _eina_stat_desc(), (void*) st };
   Eina_Promise *p = data;
   Eina_Value r = EINA_VALUE_EMPTY;

   if (!eina_value_setup(&r, EINA_VALUE_TYPE_STRUCT))
     goto on_error;
   if (!eina_value_pset(&r, &value))
     goto on_error;

   eina_promise_resolve(p, r);

   return ;

 on_error:
   eina_value_flush(&r);
   eina_promise_reject(p, eina_error_get());
}

yes. in this case on success the value is the struct data for the state. for an
exe i don't have anything. it's a 0. that's it. that's all i have.

that is one reason why i kept saying that an object is the right thing to pass
here, not an value... but well. i'm obviously so incredibly wrong there so i
did exactly what you said to do and passed and int. 

> at least you could see that eina promise is not that complex... the
> only issue remaining is this one I'm pointing you.

it's still a pain. and also a pain to use with  different callback signature to
events.

> I know we don't have the eina_future_cb_compare(), but adding that
> will be usable everywhere and make your efl_task interface more
> powerful.

you didn't listen. then how do you determine the kind of error from an
executable that returns != 0 for the kind of error vs ECANCELED. ECANCELED on
linux at least is 125. that is a perfectly possible error exit code from an
executable. i shifted the error codes up by 1000000 *IF* the error code != 0.
if it's zero no error type is passed. the int type is passed instead with is
always 0. there is no other thing to return except always 0 because you
absolutely insist that promises are values not objects and they absolutely must
be a value, so there is the return code. voila. it's an int and it's always 0.
that's how it's defined for executables.

0 == success for executables. anything else is an error. that is precisely how
the promise is exposing it. i wasn't the one who designed promises to only
carry a single error value. there isn't any sensible way of converting error
CODES to strings because every executable will be different and it's on a case
by case basis. the same applies to threads.

> 
> 
> 
> > @@ -531,7 +533,7 @@ _efl_exe_efl_task_run(Eo *obj EINA_UNUSED, Efl_Exe_Data
> > *pd) _exec(cmd, pd->flags);
> >     // we couldn't exec... uh oh. HAAAAAAAALP!
> >     exit(-122);
> > -   return EINA_FALSE;
> > +   return NULL;
> 
> this is one place you could notify the main process and cause it to
> reject with the errno.

i don't see why. it's after the exec.. and it's after an exit. i put the return
there just to ensure we don't have warnings for "no return value for function".
it's after a fork in the child too... so how is this future return going to
work then? i'd need an extra side channel pipe just to pass this side band
data. i haven't done that. i don't plan to because the cost (2 more fd's per
executed process regardless if you want the stdin/out or not) is not worth it
just to fine-grain return an error code that exec failed or that fork failed vs
the actual process failing.

-- 
------------- Codito, ergo sum - "I code, therefore I am" --------------
Carsten Haitzler - ras...@rasterman.com


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to