diff -u /home/ico/Desktop/cyclone/cyclone-0.1-alpha57/hammer/coll.c miXed/cyclone/hammer/coll.c --- /home/ico/Desktop/cyclone/cyclone-0.1-alpha57/hammer/coll.c 2015-06-18 04:37:52.000000000 -0400 +++ miXed/cyclone/hammer/coll.c 2015-10-18 18:31:57.550291910 -0400 @@ -9,6 +9,9 @@ #include "common/loud.h" #include "hammer/file.h" +#include +#include + /* LATER profile for the bottlenecks of insertion and sorting */ /* LATER make sure that ``reentrancy protection hack'' is really working... */ @@ -49,6 +52,12 @@ int c_headstate; } t_collcommon; +typedef struct _coll_q /* element in a linked list of stored messages waiting to be sent out */ +{ + struct _coll_q *q_next; /* next in list */ + char *q_s; /* the string */ +} t_coll_q; + typedef struct _coll { t_object x_ob; @@ -60,11 +69,131 @@ t_outlet *x_filebangout; t_outlet *x_dumpbangout; struct _coll *x_next; + + //for thread-unsafe file i/o operations + //added by Ivica Ico Bukvic 9-24-2010 + //http://disis.music.vt.edu http://l2ork.music.vt.edu + t_clock *x_clock; + + pthread_t unsafe_t; + pthread_mutex_t unsafe_mutex; + pthread_cond_t unsafe_cond; + + t_symbol *x_s; + t_int unsafe; + t_int init; //used to make sure that the secondary thread is ready to go + + t_int threaded; //used to decide whether this should be a threaded instance + + t_coll_q *x_q; //a list of error messages to be processed } t_coll; +typedef struct _msg +{ + int m_flag; + int m_line; +} t_msg; + +typedef struct _threadedFunctionParams +{ + t_coll *x; +} t_threadedFunctionParams; + static t_class *coll_class; static t_class *collcommon_class; +static void coll_q_free(t_coll *x) +{ + //fprintf(stderr,"coll_q_free\n"); + t_coll_q *q2; + while (x->x_q) + { + q2 = x->x_q->q_next; + t_freebytes(x->x_q->q_s, strlen(x->x_q->q_s) + 1); + t_freebytes(x->x_q, sizeof(*x->x_q)); + x->x_q = q2; + } + x->x_q = NULL; +} + +static void coll_q_post(t_coll_q *q) +{ + t_coll_q *qtmp; + for (qtmp = q; qtmp; qtmp = qtmp->q_next) + { + //fprintf(stderr,"posting...%s\n", qtmp->q_s); + post("%s", qtmp->q_s); + } +} + +static void coll_q_enqueue(t_coll *x, const char *s) +{ + //fprintf(stderr,"enqueuing %s\n", s); + t_coll_q *q, *q2 = NULL; + q = (t_coll_q *)(getbytes(sizeof(*q))); + q->q_next = NULL; + q->q_s = (char *)getbytes(strlen(s) + 1); + strcpy(q->q_s, s); + if (!x->x_q) { + //fprintf(stderr,"first\n"); + x->x_q = q; + } + else { + //fprintf(stderr,"not first\n"); + q2 = x->x_q; + while (q2->q_next) + q2 = q2->q_next; + q2->q_next = q; + } +} + +static void coll_enqueue_threaded_msgs(t_coll *x, t_msg *m) +{ + //fprintf(stderr,"msgs = %d\n", m->m_flag); + char s[MAXPDSTRING]; + if (m->m_flag & 1) { + //fprintf(stderr,"0x01\n"); + sprintf(s, "coll: no coll file '%s'", x->x_s->s_name); + coll_q_enqueue(x, s); + } + if (m->m_flag & 2) { + //fprintf(stderr,"0x02\n"); + sprintf(s, "coll: error reading text file '%s'", x->x_s->s_name); + coll_q_enqueue(x, s); + } + if (m->m_flag & 4) { + //fprintf(stderr,"0x04\n"); + sprintf(s, "coll: finished reading %d lines from text file '%s'", m->m_line, x->x_s->s_name); + coll_q_enqueue(x, s); + } + if (m->m_flag & 8) { + //fprintf(stderr,"0x08\n"); + sprintf(s, "coll: error in line %d of text file '%s'", m->m_line, x->x_s->s_name); + coll_q_enqueue(x, s); + } + if (m->m_flag & 16) { + //fprintf(stderr,"0x16\n"); + sprintf(s, "coll: error reading text file '%s'", x->x_s->s_name); + coll_q_enqueue(x, s); + } + if (m->m_flag & 32) { + //fprintf(stderr,"0x32\n"); + sprintf(s, "coll: error writing text file '%s'", x->x_s->s_name); + coll_q_enqueue(x, s); + } +} + +static void coll_tick(t_coll *x) +{ + //x->busy = 0; + if (x->x_q) + { + coll_q_post(x->x_q); + coll_q_free(x); + } + outlet_bang(x->x_filebangout); +} + static t_collelem *collelem_new(int ac, t_atom *av, int *np, t_symbol *s) { t_collelem *ep = (t_collelem *)getbytes(sizeof(*ep)); @@ -201,6 +330,8 @@ } } + + /* atomic collcommon modifiers: clearall, remove, replace, putbefore, putafter, swaplinks, swapkeys, changesymkey, renumber, sort */ @@ -582,63 +713,89 @@ return (collcommon_fromatoms(cc, binbuf_getnatom(bb), binbuf_getvec(bb))); } -static void collcommon_doread(t_collcommon *cc, t_symbol *fn, t_canvas *cv) +static t_msg *collcommon_doread(t_collcommon *cc, t_symbol *fn, t_canvas *cv, int threaded) { t_binbuf *bb; + t_msg *m = (t_msg *)(getbytes(sizeof(*m))); + m->m_flag = 0; + m->m_line = 0; char buf[MAXPDSTRING]; + if (!fn && !(fn = cc->c_filename)) /* !fn: 'readagain' */ - return; + return(m); + /* FIXME use open_via_path() */ if (cv || (cv = cc->c_lastcanvas)) /* !cv: 'read' w/o arg, 'readagain' */ - canvas_makefilename(cv, fn->s_name, buf, MAXPDSTRING); + canvas_makefilename(cv, fn->s_name, buf, MAXPDSTRING); else { strncpy(buf, fn->s_name, MAXPDSTRING); buf[MAXPDSTRING-1] = 0; } + if (!cc->c_refs) { - /* loading during object creation -- - avoid binbuf_read()'s complaints, LATER rethink */ - FILE *fp; - if (!(fp = sys_fopen(buf, "r"))) - { - loud_warning(&coll_class, 0, "no coll file '%s'", buf); - return; - } - fclose(fp); + /* loading during object creation -- + avoid binbuf_read()'s complaints, LATER rethink */ + FILE *fp; + char fname[MAXPDSTRING]; + sys_bashfilename(buf, fname); + if (!(fp = fopen(fname, "r"))) + { + m->m_flag |= 0x01; + if (!threaded) + loud_warning(&coll_class, 0, "no coll file '%s'", fname); + return(m); + } + fclose(fp); } + bb = binbuf_new(); if (binbuf_read(bb, buf, "", 0)) - loud_error(0, "coll: error reading text file '%s'", fn->s_name); - else - { - int nlines = collcommon_frombinbuf(cc, bb); - if (nlines > 0) { - t_coll *x; - /* LATER consider making this more robust */ - for (x = cc->c_refs; x; x = x->x_next) - outlet_bang(x->x_filebangout); - cc->c_lastcanvas = cv; - cc->c_filename = fn; - post("coll: finished reading %d lines from text file '%s'", - nlines, fn->s_name); - } - else if (nlines < 0) - loud_error(0, "coll: error in line %d of text file '%s'", - 1 - nlines, fn->s_name); - else - loud_error(0, "coll: error reading text file '%s'", fn->s_name); - if (cc->c_refs) - collcommon_modified(cc, 1); - } + m->m_flag |= 0x02; + if (!threaded) + loud_error(0, "coll: error reading text file '%s'", fn->s_name); + } + else if (!binbuf_read(bb, buf, "", 0)) + { + int nlines = collcommon_frombinbuf(cc, bb); + if (nlines > 0) + { + t_coll *x; + /* LATER consider making this more robust */ + for (x = cc->c_refs; x; x = x->x_next) + //outlet_bang(x->x_filebangout); + cc->c_lastcanvas = cv; + cc->c_filename = fn; + m->m_flag |= 0x04; + m->m_line = nlines; + if (!threaded) + post("coll: finished reading %d lines from text file '%s'", + nlines, fn->s_name); + } + else if (nlines < 0) { + m->m_flag |= 0x08; + m->m_line = 1 - nlines; + if (!threaded) + loud_error(0, "coll: error in line %d of text file '%s'", + 1 - nlines, fn->s_name); + } + else { + m->m_flag |= 0x16; + if (!threaded) + loud_error(0, "coll: error reading text file '%s'", fn->s_name); + } + if (cc->c_refs) + collcommon_modified(cc, 1); + } binbuf_free(bb); + return(m); } static void collcommon_readhook(t_pd *z, t_symbol *fn, int ac, t_atom *av) { - collcommon_doread((t_collcommon *)z, fn, 0); + collcommon_doread((t_collcommon *)z, fn, 0, 0); } static void collcommon_tobinbuf(t_collcommon *cc, t_binbuf *bb) @@ -666,14 +823,17 @@ } } -static void collcommon_dowrite(t_collcommon *cc, t_symbol *fn, t_canvas *cv) +static t_msg *collcommon_dowrite(t_collcommon *cc, t_symbol *fn, t_canvas *cv, int threaded) { t_binbuf *bb; int ac; t_atom *av; + t_msg *m = (t_msg *)(getbytes(sizeof(*m))); + m->m_flag = 0; + m->m_line = 0; char buf[MAXPDSTRING]; if (!fn && !(fn = cc->c_filename)) /* !fn: 'writeagain' */ - return; + return(0); if (cv || (cv = cc->c_lastcanvas)) /* !cv: 'write' w/o arg, 'writeagain' */ canvas_makefilename(cv, fn->s_name, buf, MAXPDSTRING); else @@ -683,19 +843,24 @@ } bb = binbuf_new(); collcommon_tobinbuf(cc, bb); - if (binbuf_write(bb, buf, "", 0)) - loud_error(0, "coll: error writing text file '%s'", fn->s_name); + if (binbuf_write(bb, buf, "", 0)) { + m->m_flag |= 0x32; + if (!threaded) + loud_error(0, "coll: error writing text file '%s'", fn->s_name); + } else - { - cc->c_lastcanvas = cv; - cc->c_filename = fn; - } + if (!binbuf_write(bb, buf, "", 0)) + { + cc->c_lastcanvas = cv; + cc->c_filename = fn; + } binbuf_free(bb); + return(m); } static void collcommon_writehook(t_pd *z, t_symbol *fn, int ac, t_atom *av) { - collcommon_dowrite((t_collcommon *)z, fn, 0); + collcommon_dowrite((t_collcommon *)z, fn, 0, 0); } static void coll_embedhook(t_pd *z, t_binbuf *bb, t_symbol *bindsym) @@ -823,11 +988,17 @@ cc = (t_collcommon *)collcommon_new(); cc->c_refs = 0; cc->c_increation = 0; + //x->x_common = cc; + //x->x_s = name; if (name) { pd_bind(&cc->c_pd, name); /* LATER rethink canvas unpredictability */ - collcommon_doread(cc, name, x->x_canvas); + //x->unsafe = 1; + //pthread_mutex_lock(&x->unsafe_mutex); + //pthread_cond_signal(&x->unsafe_cond); + //pthread_mutex_unlock(&x->unsafe_mutex); + collcommon_doread(cc, name, x->x_canvas, 0); } else { @@ -950,234 +1121,264 @@ static void coll_float(t_coll *x, t_float f) { - t_collcommon *cc = x->x_common; - t_collelem *ep; - int numkey; - if (loud_checkint((t_pd *)x, f, &numkey, &s_float) && - (ep = collcommon_numkey(cc, numkey))) - { - coll_keyoutput(x, ep); - if (!cc->c_selfmodified || (ep = collcommon_numkey(cc, numkey))) - coll_dooutput(x, ep->e_size, ep->e_data); - } + //if (!x->busy) { + t_collcommon *cc = x->x_common; + t_collelem *ep; + int numkey; + if (loud_checkint((t_pd *)x, f, &numkey, &s_float) && + (ep = collcommon_numkey(cc, numkey))) + { + coll_keyoutput(x, ep); + if (!cc->c_selfmodified || (ep = collcommon_numkey(cc, numkey))) + coll_dooutput(x, ep->e_size, ep->e_data); + } + //} } static void coll_symbol(t_coll *x, t_symbol *s) { - t_collcommon *cc = x->x_common; - t_collelem *ep; - if (ep = collcommon_symkey(cc, s)) - { - coll_keyoutput(x, ep); - if (!cc->c_selfmodified || (ep = collcommon_symkey(cc, s))) - coll_dooutput(x, ep->e_size, ep->e_data); - } + //if (!x->busy) { + t_collcommon *cc = x->x_common; + t_collelem *ep; + if (ep = collcommon_symkey(cc, s)) + { + coll_keyoutput(x, ep); + if (!cc->c_selfmodified || (ep = collcommon_symkey(cc, s))) + coll_dooutput(x, ep->e_size, ep->e_data); + } + //} } static void coll_list(t_coll *x, t_symbol *s, int ac, t_atom *av) { - if (ac >= 2 && av->a_type == A_FLOAT) - coll_tokey(x, av, ac-1, av+1, 1, &s_list); - else - loud_messarg((t_pd *)x, &s_list); + //if (!x->busy) { + if (ac >= 2 && av->a_type == A_FLOAT) + coll_tokey(x, av, ac-1, av+1, 1, &s_list); + else + loud_messarg((t_pd *)x, &s_list); + //} } static void coll_anything(t_coll *x, t_symbol *s, int ac, t_atom *av) { - coll_symbol(x, s); + //if (!x->busy) + coll_symbol(x, s); } static void coll_store(t_coll *x, t_symbol *s, int ac, t_atom *av) { - if (ac >= 2) - coll_tokey(x, av, ac-1, av+1, 1, s); - else - loud_messarg((t_pd *)x, s); + //if (!x->busy) { + if (ac >= 2) + coll_tokey(x, av, ac-1, av+1, 1, s); + else + loud_messarg((t_pd *)x, s); + //} } static void coll_nstore(t_coll *x, t_symbol *s, int ac, t_atom *av) { - if (ac >= 3) - { - t_collcommon *cc = x->x_common; - t_collelem *ep; - int numkey; - if (av->a_type == A_FLOAT && av[1].a_type == A_SYMBOL) - { - if (loud_checkint((t_pd *)x, av->a_w.w_float, &numkey, s)) - { - if (ep = collcommon_symkey(cc, av[1].a_w.w_symbol)) - collcommon_remove(cc, ep); - ep = collcommon_tonumkey(cc, numkey, ac-2, av+2, 1); - ep->e_symkey = av[1].a_w.w_symbol; - } - } - else if (av->a_type == A_SYMBOL && av[1].a_type == A_FLOAT) - { - if (loud_checkint((t_pd *)x, av[1].a_w.w_float, &numkey, s)) - { - if (ep = collcommon_numkey(cc, numkey)) - collcommon_remove(cc, ep); - ep = collcommon_tosymkey(cc, av->a_w.w_symbol, ac-2, av+2, 1); - ep->e_hasnumkey = 1; - ep->e_numkey = numkey; - } - } - else loud_messarg((t_pd *)x, s); - } - else loud_messarg((t_pd *)x, s); + //if (!x->busy) { + if (ac >= 3) + { + t_collcommon *cc = x->x_common; + t_collelem *ep; + int numkey; + if (av->a_type == A_FLOAT && av[1].a_type == A_SYMBOL) + { + if (loud_checkint((t_pd *)x, av->a_w.w_float, &numkey, s)) + { + if (ep = collcommon_symkey(cc, av[1].a_w.w_symbol)) + collcommon_remove(cc, ep); + ep = collcommon_tonumkey(cc, numkey, ac-2, av+2, 1); + ep->e_symkey = av[1].a_w.w_symbol; + } + } + else if (av->a_type == A_SYMBOL && av[1].a_type == A_FLOAT) + { + if (loud_checkint((t_pd *)x, av[1].a_w.w_float, &numkey, s)) + { + if (ep = collcommon_numkey(cc, numkey)) + collcommon_remove(cc, ep); + ep = collcommon_tosymkey(cc, av->a_w.w_symbol, ac-2, av+2, 1); + ep->e_hasnumkey = 1; + ep->e_numkey = numkey; + } + } + else loud_messarg((t_pd *)x, s); + } + else loud_messarg((t_pd *)x, s); + //} } static void coll_insert(t_coll *x, t_symbol *s, int ac, t_atom *av) { - if (ac >= 2 && av->a_type == A_FLOAT) - coll_tokey(x, av, ac-1, av+1, 0, s); - else - loud_messarg((t_pd *)x, s); + //if (!x->busy) { + if (ac >= 2 && av->a_type == A_FLOAT) + coll_tokey(x, av, ac-1, av+1, 0, s); + else + loud_messarg((t_pd *)x, s); + //} } static void coll_remove(t_coll *x, t_symbol *s, int ac, t_atom *av) { - if (ac) - { - t_collelem *ep; - if (ep = coll_findkey(x, av, s)) - collcommon_remove(x->x_common, ep); - } - else loud_messarg((t_pd *)x, s); + //if (!x->busy) { + if (ac) + { + t_collelem *ep; + if (ep = coll_findkey(x, av, s)) + collcommon_remove(x->x_common, ep); + } + else loud_messarg((t_pd *)x, s); + //} } static void coll_delete(t_coll *x, t_symbol *s, int ac, t_atom *av) { - if (ac) - { - t_collelem *ep; - if (ep = coll_findkey(x, av, s)) - { - if (av->a_type == A_FLOAT) - { - int numkey = ep->e_numkey; - t_collelem *next; - for (next = ep->e_next; next; next = next->e_next) - if (next->e_hasnumkey && next->e_numkey > numkey) - next->e_numkey--; - } - collcommon_remove(x->x_common, ep); - } - } - else loud_messarg((t_pd *)x, s); + //if (!x->busy) { + if (ac) + { + t_collelem *ep; + if (ep = coll_findkey(x, av, s)) + { + if (av->a_type == A_FLOAT) + { + int numkey = ep->e_numkey; + t_collelem *next; + for (next = ep->e_next; next; next = next->e_next) + if (next->e_hasnumkey && next->e_numkey > numkey) + next->e_numkey--; + } + collcommon_remove(x->x_common, ep); + } + } + else loud_messarg((t_pd *)x, s); + //} } static void coll_assoc(t_coll *x, t_symbol *s, t_floatarg f) { - int numkey; - if (loud_checkint((t_pd *)x, f, &numkey, gensym("assoc"))) - { - t_collcommon *cc = x->x_common; - t_collelem *ep1, *ep2; - if ((ep1 = collcommon_numkey(cc, numkey)) && - ep1->e_symkey != s) /* LATER rethink */ - { - if (ep2 = collcommon_symkey(cc, s)) - collcommon_remove(cc, ep2); - collcommon_changesymkey(cc, ep1, s); - } - } + //if (!x->busy) { + int numkey; + if (loud_checkint((t_pd *)x, f, &numkey, gensym("assoc"))) + { + t_collcommon *cc = x->x_common; + t_collelem *ep1, *ep2; + if ((ep1 = collcommon_numkey(cc, numkey)) && + ep1->e_symkey != s) /* LATER rethink */ + { + if (ep2 = collcommon_symkey(cc, s)) + collcommon_remove(cc, ep2); + collcommon_changesymkey(cc, ep1, s); + } + } + //} } static void coll_deassoc(t_coll *x, t_symbol *s, t_floatarg f) { - int numkey; - if (loud_checkint((t_pd *)x, f, &numkey, gensym("deassoc"))) - { - t_collcommon *cc = x->x_common; - t_collelem *ep; - if (ep = collcommon_numkey(cc, numkey)) - collcommon_changesymkey(cc, ep, 0); - } + //if (!x->busy) { + int numkey; + if (loud_checkint((t_pd *)x, f, &numkey, gensym("deassoc"))) + { + t_collcommon *cc = x->x_common; + t_collelem *ep; + if (ep = collcommon_numkey(cc, numkey)) + collcommon_changesymkey(cc, ep, 0); + } + //} } static void coll_subsym(t_coll *x, t_symbol *s1, t_symbol *s2) { - t_collelem *ep; - if (s1 != s2 && (ep = collcommon_symkey(x->x_common, s2))) - collcommon_changesymkey(x->x_common, ep, s1); + //if (!x->busy) { + t_collelem *ep; + if (s1 != s2 && (ep = collcommon_symkey(x->x_common, s2))) + collcommon_changesymkey(x->x_common, ep, s1); + //} } static void coll_renumber(t_coll *x, t_floatarg f) { - int startkey; - if (loud_checkint((t_pd *)x, f, &startkey, gensym("renumber"))) - collcommon_renumber(x->x_common, startkey); + //if (!x->busy) { + int startkey; + if (loud_checkint((t_pd *)x, f, &startkey, gensym("renumber"))) + collcommon_renumber(x->x_common, startkey); + //} } static void coll_merge(t_coll *x, t_symbol *s, int ac, t_atom *av) { - if (ac >= 2) - { - t_collcommon *cc = x->x_common; - t_collelem *ep; - if (av->a_type == A_FLOAT) - { - int numkey; - if (loud_checkint((t_pd *)x, av->a_w.w_float, &numkey, s)) - { - if (ep = collcommon_numkey(cc, numkey)) - collcommon_adddata(cc, ep, ac-1, av+1); - else /* LATER consider defining collcommon_toclosest() */ - collcommon_tonumkey(cc, numkey, ac-1, av+1, 1); - } - } - else if (av->a_type == A_SYMBOL) - { - if (ep = collcommon_symkey(cc, av->a_w.w_symbol)) - collcommon_adddata(cc, ep, ac-1, av+1); - else - { - ep = collelem_new(ac-1, av+1, 0, av->a_w.w_symbol); - collcommon_putafter(cc, ep, cc->c_last); - } - } - else loud_messarg((t_pd *)x, s); - } - else loud_messarg((t_pd *)x, s); + //if (!x->busy) { + if (ac >= 2) + { + t_collcommon *cc = x->x_common; + t_collelem *ep; + if (av->a_type == A_FLOAT) + { + int numkey; + if (loud_checkint((t_pd *)x, av->a_w.w_float, &numkey, s)) + { + if (ep = collcommon_numkey(cc, numkey)) + collcommon_adddata(cc, ep, ac-1, av+1); + else /* LATER consider defining collcommon_toclosest() */ + collcommon_tonumkey(cc, numkey, ac-1, av+1, 1); + } + } + else if (av->a_type == A_SYMBOL) + { + if (ep = collcommon_symkey(cc, av->a_w.w_symbol)) + collcommon_adddata(cc, ep, ac-1, av+1); + else + { + ep = collelem_new(ac-1, av+1, 0, av->a_w.w_symbol); + collcommon_putafter(cc, ep, cc->c_last); + } + } + else loud_messarg((t_pd *)x, s); + } + else loud_messarg((t_pd *)x, s); + //} } static void coll_sub(t_coll *x, t_symbol *s, int ac, t_atom *av) { - if (ac) - { - t_collelem *ep; - if (ep = coll_findkey(x, av, s)) - { - t_collcommon *cc = x->x_common; - t_atom *key = av++; - ac--; - while (ac >= 2) - { - if (av->a_type == A_FLOAT) + //if (!x->busy) { + if (ac) { - int ndx; - if (loud_checkint((t_pd *)x, av->a_w.w_float, &ndx, 0) - && ndx >= 1 && ndx <= ep->e_size) - ep->e_data[ndx-1] = av[1]; + t_collelem *ep; + if (ep = coll_findkey(x, av, s)) + { + t_collcommon *cc = x->x_common; + t_atom *key = av++; + ac--; + while (ac >= 2) + { + if (av->a_type == A_FLOAT) + { + int ndx; + if (loud_checkint((t_pd *)x, av->a_w.w_float, &ndx, 0) + && ndx >= 1 && ndx <= ep->e_size) + ep->e_data[ndx-1] = av[1]; + } + ac -= 2; + av += 2; + } + if (s == gensym("sub")) + { + coll_keyoutput(x, ep); + if (!cc->c_selfmodified || (ep = coll_findkey(x, key, 0))) + coll_dooutput(x, ep->e_size, ep->e_data); + } + } } - ac -= 2; - av += 2; - } - if (s == gensym("sub")) - { - coll_keyoutput(x, ep); - if (!cc->c_selfmodified || (ep = coll_findkey(x, key, 0))) - coll_dooutput(x, ep->e_size, ep->e_data); - } - } - } - else loud_messarg((t_pd *)x, s); + else loud_messarg((t_pd *)x, s); + //} } static void coll_sort(t_coll *x, t_floatarg f1, t_floatarg f2) { + int dir, ndx; if (loud_checkint((t_pd *)x, f1, &dir, gensym("sort")) && loud_checkint((t_pd *)x, f2, &ndx, gensym("sort"))) @@ -1195,14 +1396,16 @@ needed in case of their implementation... */ static void coll_swap(t_coll *x, t_symbol *s, int ac, t_atom *av) { - if (ac == 2) - { - t_collelem *ep1, *ep2; - if ((ep1 = coll_findkey(x, av, s)) && - (ep2 = coll_findkey(x, av + 1, s))) - collcommon_swapkeys(x->x_common, ep1, ep2); - } - else loud_messarg((t_pd *)x, s); + //if (!x->busy) { + if (ac == 2) + { + t_collelem *ep1, *ep2; + if ((ep1 = coll_findkey(x, av, s)) && + (ep2 = coll_findkey(x, av + 1, s))) + collcommon_swapkeys(x->x_common, ep1, ep2); + } + else loud_messarg((t_pd *)x, s); + //} } /* CHECKED traversal direction change is consistent with the general rule: @@ -1214,212 +1417,296 @@ static void coll_next(t_coll *x) { - t_collcommon *cc = x->x_common; - if (cc->c_headstate != COLL_HEADRESET && - cc->c_headstate != COLL_HEADDELETED) /* asymmetric, LATER rethink */ - { - if (cc->c_head) - cc->c_head = cc->c_head->e_next; - if (!cc->c_head && !(cc->c_head = cc->c_first)) /* CHECKED wrapping */ - return; - } - else if (!cc->c_head && !(cc->c_head = cc->c_first)) - return; - cc->c_headstate = COLL_HEADNEXT; - coll_keyoutput(x, cc->c_head); - if (cc->c_head) - coll_dooutput(x, cc->c_head->e_size, cc->c_head->e_data); - else if (!cc->c_selfmodified) - loudbug_bug("coll_next"); /* LATER rethink */ + //if (!x->busy) { + t_collcommon *cc = x->x_common; + if (cc->c_headstate != COLL_HEADRESET && + cc->c_headstate != COLL_HEADDELETED) /* asymmetric, LATER rethink */ + { + if (cc->c_head) + cc->c_head = cc->c_head->e_next; + if (!cc->c_head && !(cc->c_head = cc->c_first)) /* CHECKED wrapping */ + return; + } + else if (!cc->c_head && !(cc->c_head = cc->c_first)) + return; + cc->c_headstate = COLL_HEADNEXT; + coll_keyoutput(x, cc->c_head); + if (cc->c_head) + coll_dooutput(x, cc->c_head->e_size, cc->c_head->e_data); + else if (!cc->c_selfmodified) + loudbug_bug("coll_next"); /* LATER rethink */ + //} } static void coll_prev(t_coll *x) { - t_collcommon *cc = x->x_common; - if (cc->c_headstate != COLL_HEADRESET) - { - if (cc->c_head) - cc->c_head = cc->c_head->e_prev; - if (!cc->c_head && !(cc->c_head = cc->c_last)) /* CHECKED wrapping */ - return; - } - else if (!cc->c_head && !(cc->c_head = cc->c_first)) - return; - cc->c_headstate = COLL_HEADPREV; - coll_keyoutput(x, cc->c_head); - if (cc->c_head) - coll_dooutput(x, cc->c_head->e_size, cc->c_head->e_data); - else if (!cc->c_selfmodified) - loudbug_bug("coll_prev"); /* LATER rethink */ + //if (!x->busy) { + t_collcommon *cc = x->x_common; + if (cc->c_headstate != COLL_HEADRESET) + { + if (cc->c_head) + cc->c_head = cc->c_head->e_prev; + if (!cc->c_head && !(cc->c_head = cc->c_last)) /* CHECKED wrapping */ + return; + } + else if (!cc->c_head && !(cc->c_head = cc->c_first)) + return; + cc->c_headstate = COLL_HEADPREV; + coll_keyoutput(x, cc->c_head); + if (cc->c_head) + coll_dooutput(x, cc->c_head->e_size, cc->c_head->e_data); + else if (!cc->c_selfmodified) + loudbug_bug("coll_prev"); /* LATER rethink */ + //} +} + +static void coll_start(t_coll *x) +{ + //if (!x->busy) { + t_collcommon *cc = x->x_common; + cc->c_head = cc->c_first; + cc->c_headstate = COLL_HEADRESET; + //} } static void coll_end(t_coll *x) { - t_collcommon *cc = x->x_common; - cc->c_head = cc->c_last; - cc->c_headstate = COLL_HEADRESET; + //if (!x->busy) { + t_collcommon *cc = x->x_common; + cc->c_head = cc->c_last; + cc->c_headstate = COLL_HEADRESET; + //} } static void coll_goto(t_coll *x, t_symbol *s, int ac, t_atom *av) { - if (ac) - { - t_collelem *ep = coll_findkey(x, av, s); - if (ep) - { - t_collcommon *cc = x->x_common; - cc->c_head = ep; - cc->c_headstate = COLL_HEADRESET; - } - } - else loud_messarg((t_pd *)x, s); + //if (!x->busy) { + if (ac) + { + t_collelem *ep = coll_findkey(x, av, s); + if (ep) + { + t_collcommon *cc = x->x_common; + cc->c_head = ep; + cc->c_headstate = COLL_HEADRESET; + } + } + //else loud_messarg((t_pd *)x, s); + else coll_start(x); + //} } static void coll_nth(t_coll *x, t_symbol *s, int ac, t_atom *av) { - if (ac >= 2 && av[1].a_type == A_FLOAT) - { - int ndx; - t_collelem *ep; - if (loud_checkint((t_pd *)x, av[1].a_w.w_float, &ndx, s) && - (ep = coll_findkey(x, av, s)) && - ep->e_size >= ndx) - { - t_atom *ap = ep->e_data + --ndx; - if (ap->a_type == A_FLOAT) - outlet_float(((t_object *)x)->ob_outlet, ap->a_w.w_float); - else if (ap->a_type == A_SYMBOL) - outlet_symbol(((t_object *)x)->ob_outlet, ap->a_w.w_symbol); - } - } - else loud_messarg((t_pd *)x, s); + //if (!x->busy) { + if (ac >= 2 && av[1].a_type == A_FLOAT) + { + int ndx; + t_collelem *ep; + if (loud_checkint((t_pd *)x, av[1].a_w.w_float, &ndx, s) && + (ep = coll_findkey(x, av, s)) && + ep->e_size >= ndx) + { + t_atom *ap = ep->e_data + --ndx; + if (ap->a_type == A_FLOAT) + outlet_float(((t_object *)x)->ob_outlet, ap->a_w.w_float); + else if (ap->a_type == A_SYMBOL) + outlet_symbol(((t_object *)x)->ob_outlet, ap->a_w.w_symbol); + } + } + else loud_messarg((t_pd *)x, s); + //} } static void coll_length(t_coll *x) { - t_collcommon *cc = x->x_common; - t_collelem *ep = cc->c_first; - int result = 0; - while (ep) result++, ep = ep->e_next; - outlet_float(((t_object *)x)->ob_outlet, result); + //if (!x->busy) { + t_collcommon *cc = x->x_common; + t_collelem *ep = cc->c_first; + int result = 0; + while (ep) result++, ep = ep->e_next; + outlet_float(((t_object *)x)->ob_outlet, result); + //} } static void coll_min(t_coll *x, t_floatarg f) { - int ndx; - if (loud_checkint((t_pd *)x, f, &ndx, gensym("min"))) - { - t_collelem *found; - if (ndx > 0) - ndx--; - /* LATER consider complaining: */ - else if (ndx < 0) - return; /* CHECKED silently rejected */ - /* else CHECKED silently defaults to 1 */ - if (found = coll_firsttyped(x, ndx, A_FLOAT)) - { - t_float result = found->e_data[ndx].a_w.w_float; - t_collelem *ep; - for (ep = found->e_next; ep; ep = ep->e_next) - { - if (ep->e_size > ndx && - ep->e_data[ndx].a_type == A_FLOAT && - ep->e_data[ndx].a_w.w_float < result) + //if (!x->busy) { + int ndx; + if (loud_checkint((t_pd *)x, f, &ndx, gensym("min"))) { - found = ep; - result = ep->e_data[ndx].a_w.w_float; + t_collelem *found; + if (ndx > 0) + ndx--; + /* LATER consider complaining: */ + else if (ndx < 0) + return; /* CHECKED silently rejected */ + /* else CHECKED silently defaults to 1 */ + if (found = coll_firsttyped(x, ndx, A_FLOAT)) + { + t_float result = found->e_data[ndx].a_w.w_float; + t_collelem *ep; + for (ep = found->e_next; ep; ep = ep->e_next) + { + if (ep->e_size > ndx && + ep->e_data[ndx].a_type == A_FLOAT && + ep->e_data[ndx].a_w.w_float < result) + { + found = ep; + result = ep->e_data[ndx].a_w.w_float; + } + } + coll_keyoutput(x, found); + outlet_float(((t_object *)x)->ob_outlet, result); + } } - } - coll_keyoutput(x, found); - outlet_float(((t_object *)x)->ob_outlet, result); - } - } + //} } static void coll_max(t_coll *x, t_floatarg f) { - int ndx; - if (loud_checkint((t_pd *)x, f, &ndx, gensym("max"))) - { - t_collelem *found; - if (ndx > 0) - ndx--; - /* LATER consider complaining: */ - else if (ndx < 0) - return; /* CHECKED silently rejected */ - /* else CHECKED silently defaults to 1 */ - if (found = coll_firsttyped(x, ndx, A_FLOAT)) - { - t_float result = found->e_data[ndx].a_w.w_float; - t_collelem *ep; - for (ep = found->e_next; ep; ep = ep->e_next) - { - if (ep->e_size > ndx && - ep->e_data[ndx].a_type == A_FLOAT && - ep->e_data[ndx].a_w.w_float > result) + //if (!x->busy) { + int ndx; + if (loud_checkint((t_pd *)x, f, &ndx, gensym("max"))) { - found = ep; - result = ep->e_data[ndx].a_w.w_float; + t_collelem *found; + if (ndx > 0) + ndx--; + /* LATER consider complaining: */ + else if (ndx < 0) + return; /* CHECKED silently rejected */ + /* else CHECKED silently defaults to 1 */ + if (found = coll_firsttyped(x, ndx, A_FLOAT)) + { + t_float result = found->e_data[ndx].a_w.w_float; + t_collelem *ep; + for (ep = found->e_next; ep; ep = ep->e_next) + { + if (ep->e_size > ndx && + ep->e_data[ndx].a_type == A_FLOAT && + ep->e_data[ndx].a_w.w_float > result) + { + found = ep; + result = ep->e_data[ndx].a_w.w_float; + } + } + coll_keyoutput(x, found); + outlet_float(((t_object *)x)->ob_outlet, result); + } } - } - coll_keyoutput(x, found); - outlet_float(((t_object *)x)->ob_outlet, result); - } - } + //} } static void coll_refer(t_coll *x, t_symbol *s) { - if (!coll_rebind(x, s)) - { - /* LATER consider complaining */ - } + //if (!x->busy) { + if (!coll_rebind(x, s)) + { + /* LATER consider complaining */ + } + //} } static void coll_flags(t_coll *x, t_float f1, t_float f2) { - int i1; - if (loud_checkint((t_pd *)x, f1, &i1, gensym("flags"))) - { - t_collcommon *cc = x->x_common; - cc->c_embedflag = (i1 != 0); - } + //if (!x->busy) { + int i1; + if (loud_checkint((t_pd *)x, f1, &i1, gensym("flags"))) + { + t_collcommon *cc = x->x_common; + cc->c_embedflag = (i1 != 0); + } + //} } static void coll_read(t_coll *x, t_symbol *s) { - t_collcommon *cc = x->x_common; - if (s && s != &s_) - collcommon_doread(cc, s, x->x_canvas); - else - hammerpanel_open(cc->c_filehandle, 0); + if (!x->unsafe) { + t_collcommon *cc = x->x_common; + if (s && s != &s_) { + x->x_s = s; + if (x->threaded == 1) { + x->unsafe = 1; + + pthread_mutex_lock(&x->unsafe_mutex); + pthread_cond_signal(&x->unsafe_cond); + pthread_mutex_unlock(&x->unsafe_mutex); + //collcommon_doread(cc, s, x->x_canvas, 0); + } + else { + collcommon_doread(cc, s, x->x_canvas, 0); + } + } + else + hammerpanel_open(cc->c_filehandle, 0); + } } static void coll_write(t_coll *x, t_symbol *s) { - t_collcommon *cc = x->x_common; - if (s && s != &s_) - collcommon_dowrite(cc, s, x->x_canvas); - else - hammerpanel_save(cc->c_filehandle, 0, 0); /* CHECKED no default name */ + if (!x->unsafe) { + t_collcommon *cc = x->x_common; + if (s && s != &s_) { + x->x_s = s; + if (x->threaded == 1) { + x->unsafe = 10; + + pthread_mutex_lock(&x->unsafe_mutex); + pthread_cond_signal(&x->unsafe_cond); + pthread_mutex_unlock(&x->unsafe_mutex); + //collcommon_dowrite(cc, s, x->x_canvas, 0); + } + else { + collcommon_dowrite(cc, s, x->x_canvas, 0); + } + } + else + hammerpanel_save(cc->c_filehandle, 0, 0); /* CHECKED no default name */ + } } static void coll_readagain(t_coll *x) { - t_collcommon *cc = x->x_common; - if (cc->c_filename) - collcommon_doread(cc, 0, 0); - else - hammerpanel_open(cc->c_filehandle, 0); + //if (!x->busy) { + t_collcommon *cc = x->x_common; + if (cc->c_filename) { + if (x->threaded == 1) { + x->unsafe = 2; + + pthread_mutex_lock(&x->unsafe_mutex); + pthread_cond_signal(&x->unsafe_cond); + pthread_mutex_unlock(&x->unsafe_mutex); + //collcommon_doread(cc, 0, 0, 0); + } + else { + collcommon_doread(cc, 0, 0, 0); + } + } + else + hammerpanel_open(cc->c_filehandle, 0); + //} } static void coll_writeagain(t_coll *x) { - t_collcommon *cc = x->x_common; - if (cc->c_filename) - collcommon_dowrite(cc, 0, 0); - else - hammerpanel_save(cc->c_filehandle, 0, 0); /* CHECKED no default name */ + //if (!x->busy) { + t_collcommon *cc = x->x_common; + if (cc->c_filename) { + if (x->threaded == 1) { + x->unsafe = 11; + + pthread_mutex_lock(&x->unsafe_mutex); + pthread_cond_signal(&x->unsafe_cond); + pthread_mutex_unlock(&x->unsafe_mutex); + //collcommon_dowrite(cc, 0, 0, 0); + } + else { + collcommon_dowrite(cc, 0, 0, 0); + } + } + else + hammerpanel_save(cc->c_filehandle, 0, 0); /* CHECKED no default name */ + //} } static void coll_filetype(t_coll *x, t_symbol *s) @@ -1429,17 +1716,19 @@ static void coll_dump(t_coll *x) { - t_collcommon *cc = x->x_common; - t_collelem *ep; - for (ep = cc->c_first; ep; ep = ep->e_next) - { - coll_keyoutput(x, ep); - if (cc->c_selfmodified) - break; - coll_dooutput(x, ep->e_size, ep->e_data); - /* FIXME dooutput() may invalidate ep as well as keyoutput()... */ - } - outlet_bang(x->x_dumpbangout); + //if (!x->busy) { + t_collcommon *cc = x->x_common; + t_collelem *ep; + for (ep = cc->c_first; ep; ep = ep->e_next) + { + coll_keyoutput(x, ep); + if (cc->c_selfmodified) + break; + coll_dooutput(x, ep->e_size, ep->e_data); + /* FIXME dooutput() may invalidate ep as well as keyoutput()... */ + } + outlet_bang(x->x_dumpbangout); + //} } static void coll_open(t_coll *x) @@ -1490,15 +1779,17 @@ #ifdef COLL_DEBUG static void collelem_post(t_collelem *ep) { - if (ep->e_hasnumkey && ep->e_symkey) - loudbug_startpost("%d %s:", ep->e_numkey, ep->e_symkey->s_name); - else if (ep->e_hasnumkey) - loudbug_startpost("%d:", ep->e_numkey); - else if (ep->e_symkey) - loudbug_startpost("%s:", ep->e_symkey->s_name); - else loudbug_bug("collcommon_post"); - loudbug_postatom(ep->e_size, ep->e_data); - loudbug_endpost(); + //if (!x->busy) { + if (ep->e_hasnumkey && ep->e_symkey) + loudbug_startpost("%d %s:", ep->e_numkey, ep->e_symkey->s_name); + else if (ep->e_hasnumkey) + loudbug_startpost("%d:", ep->e_numkey); + else if (ep->e_symkey) + loudbug_startpost("%s:", ep->e_symkey->s_name); + else loudbug_bug("collcommon_post"); + loudbug_postatom(ep->e_size, ep->e_data); + loudbug_endpost(); + //} } static void collcommon_post(t_collcommon *cc) @@ -1509,43 +1800,111 @@ static void coll_debug(t_coll *x, t_floatarg f) { - t_collcommon *cc = coll_checkcommon(x); - if (cc) - { - t_coll *x1 = cc->c_refs; - t_collelem *ep, *last; - int i = 0; - while (x1) i++, x1 = x1->x_next; - loudbug_post("refcount %d", i); - for (ep = cc->c_first, last = 0; ep; ep = ep->e_next) last = ep; - if (last != cc->c_last) loudbug_bug("coll_debug: last element"); - collcommon_post(cc); - } + //if (!x->busy) { + t_collcommon *cc = coll_checkcommon(x); + if (cc) + { + t_coll *x1 = cc->c_refs; + t_collelem *ep, *last; + int i = 0; + while (x1) i++, x1 = x1->x_next; + loudbug_post("refcount %d", i); + for (ep = cc->c_first, last = 0; ep; ep = ep->e_next) last = ep; + if (last != cc->c_last) loudbug_bug("coll_debug: last element"); + collcommon_post(cc); + } + //} } #endif +static void *coll_threaded_fileio(void *ptr) +{ + t_threadedFunctionParams *rPars = (t_threadedFunctionParams*)ptr; + t_coll *x = rPars->x; + t_msg *m = NULL; + + while(x->unsafe > -1) { + pthread_mutex_lock(&x->unsafe_mutex); + if (x->unsafe == 0) + if (!x->init) x->init = 1; + pthread_cond_wait(&x->unsafe_cond, &x->unsafe_mutex); + + if (x->unsafe == 1) { //read + m = collcommon_doread(x->x_common, x->x_s, x->x_canvas, 1); + if (m->m_flag) + coll_enqueue_threaded_msgs(x, m); + clock_delay(x->x_clock, 0); + } + else if (x->unsafe == 2) { //read + m = collcommon_doread(x->x_common, 0, 0, 1); + if (m->m_flag) + coll_enqueue_threaded_msgs(x, m); + clock_delay(x->x_clock, 0); + } + else if (x->unsafe == 10) { //write + m = collcommon_dowrite(x->x_common, x->x_s, x->x_canvas, 1); + if (m->m_flag) + coll_enqueue_threaded_msgs(x, m); + } + else if (x->unsafe == 11) { //write + m = collcommon_dowrite(x->x_common, 0, 0, 1); + if (m->m_flag) + coll_enqueue_threaded_msgs(x, m); + } + + if (m != NULL) + { + t_freebytes(m, sizeof(*m)); + m = NULL; + } + + if (x->unsafe != -1) x->unsafe = 0; + pthread_mutex_unlock(&x->unsafe_mutex); + } + pthread_exit(0); +} + static void coll_separate(t_coll *x, t_floatarg f) { - int indx; - t_collcommon *cc = x->x_common; - if (loud_checkint((t_pd *)x, f, &indx, gensym("separate"))) - { - t_collelem *ep; - for (ep = cc->c_first; ep; ep = ep->e_next) - if (ep->e_hasnumkey && ep->e_numkey >= indx) - ep->e_numkey += 1; - collcommon_modified(cc, 0); - } + int indx; + t_collcommon *cc = x->x_common; + if (loud_checkint((t_pd *)x, f, &indx, gensym("separate"))) + { + t_collelem *ep; + for (ep = cc->c_first; ep; ep = ep->e_next) + if (ep->e_hasnumkey && ep->e_numkey >= indx) + ep->e_numkey += 1; + collcommon_modified(cc, 0); + } } static void coll_free(t_coll *x) { + if (x->threaded == 1) + { + x->unsafe = -1; + + pthread_mutex_lock(&x->unsafe_mutex); + pthread_cond_signal(&x->unsafe_cond); + pthread_mutex_unlock(&x->unsafe_mutex); + + pthread_join(x->unsafe_t, NULL); + pthread_mutex_destroy(&x->unsafe_mutex); + + clock_free(x->x_clock); + if (x->x_q) + coll_q_free(x); + } + hammerfile_free(x->x_filehandle); coll_unbind(x); } -static void *coll_new(t_symbol *s) +static void *coll_new(t_symbol *s, int argc, t_atom *argv) { + int ret; + int count = 0; + t_symbol *file = NULL; t_coll *x = (t_coll *)pd_new(coll_class); x->x_canvas = canvas_getcurrent(); outlet_new((t_object *)x, &s_); @@ -1553,7 +1912,50 @@ x->x_filebangout = outlet_new((t_object *)x, &s_bang); x->x_dumpbangout = outlet_new((t_object *)x, &s_bang); x->x_filehandle = hammerfile_new((t_pd *)x, coll_embedhook, 0, 0, 0); - coll_bind(x, s); + + // check arguments for filename and threaded version + if (argc > 0) + { + while(count < argc) + { + if (argv[count].a_type == A_SYMBOL) + { + // we got a file name + file = gensym(atom_getsymbol(&argv[count])->s_name); + } + else if (argv[count].a_type == A_FLOAT) + { + // we got a flag for threaded (1) vs non-threaded (0) + x->threaded = (int)atom_getfloat(&argv[count]); + if (x->threaded < 0) x->threaded = 0; + if (x->threaded > 1) x->threaded = 1; + } + count++; + } + } + // if no file name provided, associate with empty symbol + if (file == NULL) + file = &s_; + + // prep threading stuff + x->unsafe = 0; + x->init = 0; + if (x->threaded == 1) + { + x->x_clock = clock_new(x, (t_method)coll_tick); + t_threadedFunctionParams rPars; + rPars.x = x; + pthread_mutex_init(&x->unsafe_mutex, NULL); + pthread_cond_init(&x->unsafe_cond, NULL); + ret = pthread_create( &x->unsafe_t, NULL, (void *) &coll_threaded_fileio, (void *) &rPars); + + while (!x->init) { + sched_yield(); + } + } + + coll_bind(x, file); + return (x); } @@ -1562,7 +1964,7 @@ coll_class = class_new(gensym("coll"), (t_newmethod)coll_new, (t_method)coll_free, - sizeof(t_coll), 0, A_DEFSYM, 0); + sizeof(t_coll), 0, A_GIMME, 0); class_addbang(coll_class, coll_next); class_addfloat(coll_class, coll_float); class_addsymbol(coll_class, coll_symbol); @@ -1620,6 +2022,8 @@ gensym("flags"), A_FLOAT, A_FLOAT, 0); class_addmethod(coll_class, (t_method)coll_read, gensym("read"), A_DEFSYM, 0); + class_addmethod(coll_class, (t_method)coll_start, + gensym("start"), 0); class_addmethod(coll_class, (t_method)coll_write, gensym("write"), A_DEFSYM, 0); class_addmethod(coll_class, (t_method)coll_readagain, @@ -1650,6 +2054,6 @@ class itself has been already set up above), but it is better to have it around, just in case... */ hammerfile_setup(collcommon_class, 0); -// logpost(NULL, 4, "this is cyclone/coll %s, %dth %s build", -// CYCLONE_VERSION, CYCLONE_BUILD, CYCLONE_RELEASE); + //logpost(NULL, 4, "this is cyclone/coll %s, %dth %s build", + //CYCLONE_VERSION, CYCLONE_BUILD, CYCLONE_RELEASE); } diff -u /home/ico/Desktop/cyclone/cyclone-0.1-alpha57/hammer/decide.c miXed/cyclone/hammer/decide.c --- /home/ico/Desktop/cyclone/cyclone-0.1-alpha57/hammer/decide.c 2015-06-18 04:37:52.000000000 -0400 +++ miXed/cyclone/hammer/decide.c 2015-10-18 18:35:48.277301861 -0400 @@ -5,6 +5,7 @@ #include "m_pd.h" #include "common/loud.h" #include "shared.h" +#include typedef struct _decide {