static int process_new_notification(pblock *param, Session *sn, Request *rq, void* agent_config) { handle_notification(sn, rq, agent_config); /* Use the protocol_status function to set the status of the * response before calling protocol_start_response. */ protocol_status(sn, rq, PROTOCOL_OK, NULL); /* Although we would expect the ObjectType stage to * set the content-type, set it here just to be * completely sure that it gets set to text/html. */ param_free(pblock_remove("content-type", rq->srvhdrs)); pblock_nvinsert("content-type", "text/html", rq->srvhdrs); pblock_nvinsert("content-length", "2", rq->srvhdrs); /* Send the headers to the client*/ protocol_start_response(sn, rq); /* Write the output using net_write*/ if (IO_ERROR == net_write(sn->csd, "OK", 2)) { return REQ_EXIT; } return REQ_PROCEED; }
/* This is the C function which allows to cause a variable change notification in the Lua VM. * Its works differently, depending on whether it's called from the thread in which the Lua * VM runs: * * * in all cases, it stores the notification description in `notify_buffer`. * * if it runs in the Lua VM thread, it calls the Lua handler directly; * * if called from another thread, it sends a Lua signal, which will trigger * the notification handler, and waits until the handling is completed; completion * is signaled by the release of a dedicated `notify_buffer->handled` mutex. */ static swi_status_t trigger_notification(void *ctx, int nvars, ExtVars_id_t* vars, void** values, ExtVars_type_t* types) { ExtVars_Mod_t *mod = (ExtVars_Mod_t *)ctx; /* make sure that only one notification is in progress. */ pthread_mutex_lock(¬ify_buffer.inprogress); notify_buffer.handler_name = mod->name; notify_buffer.nvars = nvars; notify_buffer.vars = vars; notify_buffer.values = values; notify_buffer.types = types; if(pthread_self() == notify_buffer.lua_thread) { /* Direct nested call */ handle_notification(notify_buffer.L); } else { /* Triggered through a pre-subscribed Lua signal */ LUASIGNAL_SignalT( notify_buffer.luasigctx, NOTIFY_SIGEMITTER, NOTIFY_SIGEVENT, NULL); } /* If this function runs in the lua thread, the `handled` semaphore has already been released by the * Lua notification handler. * * If this thread is not the lua thread, the lua signal sent above will eventually cause the lua * handler to run, which will eventually release the `handled` sem. * Until this happens, the current thread pauses, and the notification ctx won't be altered. */ sem_wait(¬ify_buffer.handled); pthread_mutex_unlock(¬ify_buffer.inprogress); return SWI_STATUS_OK; }
static int receive_cb(struct socket *sock, union sctp_sockstore addr, void *data, size_t datalen, struct sctp_rcvinfo rcv, int flags, void *ulp_info) { if (data) { if (flags & MSG_NOTIFICATION) { handle_notification((union sctp_notification *)data, datalen); } else { printf("Msg of length %d received via %p:%u on stream %d with SSN %u and TSN %u, PPID %d, context %u.\n", (int)datalen, addr.sconn.sconn_addr, ntohs(addr.sconn.sconn_port), rcv.rcv_sid, rcv.rcv_ssn, rcv.rcv_tsn, ntohl(rcv.rcv_ppid), rcv.rcv_context); } free(data); } else { usrsctp_deregister_address(ulp_info); usrsctp_close(sock); } return 1; }
bool ouroboros_server::set(const std::string& aGroup, const std::string& aField, const var_field& aFieldData) { var_field *result = mStore.get(normalize_group(aGroup), aField); if (!result) { return false; } result->setJSON(aFieldData.getJSON()); handle_notification(aGroup, aField); return true; }
void ouroboros_server::handle_name_rest(const rest_request& aRequest) { //get reference to named thing var_field *named = mStore.get(normalize_group(aRequest.getGroups()), aRequest.getFields()); std::string sjson; mg_connection *conn = aRequest.getConnection(); if (named) { switch (aRequest.getHttpRequestType()) { case PUT: { std::string data(conn->content, conn->content_len); JSON json(data); if (named->setJSON(json)) { handle_notification(aRequest.getGroups(), aRequest.getFields()); sjson = detail::good_JSON(); } else { sjson = detail::bad_JSON(conn); } } break; case GET: //Send JSON describing named item sjson = named->getJSON(); break; default: sjson = detail::bad_JSON(conn); } } else { sjson = detail::bad_JSON(conn); } mg_send_data(conn, sjson.c_str(), sjson.length()); }
static int receive_cb(struct socket *sock, union sctp_sockstore addr, void *data, size_t datalen, struct sctp_rcvinfo rcv, int flags, void *ulp_info) { struct peer_connection *pc; pc = (struct peer_connection *)ulp_info; if (data) { lock_peer_connection(pc); if (flags & MSG_NOTIFICATION) { handle_notification(pc, (union sctp_notification *)data, datalen); } else { handle_message(pc, data, datalen, ntohl(rcv.rcv_ppid), rcv.rcv_sid); } unlock_peer_connection(pc); } return (1); }
int sctpReadInput(int fd, distributor *o,sctpAdaptorMod *r) { /* receive some number of datagrams and act on them. */ struct sctp_sndrcvinfo *s_info; socklen_t from_len; int sz,i,disped,ll; messageEnvolope msgout; struct msghdr msg; struct iovec iov[2]; unsigned char from[200]; char readBuffer[65535]; char controlVector[65535]; disped = i = 0; from_len = sizeof(from); if((fd == mainFd) && (r->model & SCTP_TCP_TYPE) && (r->model & SCTP_TCP_IS_LISTENING)){ /* are we using TCP model here, maybe */ int newfd; newfd = accept(fd, (struct sockaddr *)from, &from_len); if(newfd != -1){ printf("New fd accepted fd=%d from:",newfd); SCTPPrintAnAddress((struct sockaddr *)from); dist_addFd(o,newfd,sctpFdInput,POLLIN,(void *)r); printf("Added new fd, now returning\n"); return(0); }else{ printf("Accept failed err:%d\n",errno); printf("Fall through and let read fail (hopefully :>)\n"); } } s_info = NULL; iov[0].iov_base = readBuffer; ll = iov[0].iov_len = sizeof(readBuffer); iov[1].iov_base = NULL; iov[1].iov_len = 0; msg.msg_name = (caddr_t)from; msg.msg_namelen = from_len; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_control = (caddr_t)controlVector; msg.msg_flags = 0; msg.msg_controllen = sizeof(controlVector); errno = 0; sz = sctp_recvmsg (fd, readBuffer, (size_t)ll, (struct sockaddr *)&from, &from_len, &o_info, &msg.msg_flags); s_info = &o_info; if(sz <= 0){ if (sz == 0) { if (fd != mainFd) { printf("Connected fd:%d gets 0/0 remove from dist\n",fd); dist_deleteFd(o,fd); return(0); } else { /* our mainFd went EOF on us... probably a 1-to-1 socket */ printf("Main fd:%d got EOF... please quit and restart now...\n",fd); close(fd); dist_deleteFd(o,fd); return(0); } } if((errno != ENOBUFS) && (errno != EAGAIN)) printf("Read returns %d errno:%d control len is %d msgflg:0x%x\n", sz,errno, msg.msg_controllen,msg.msg_flags); if(errno == EBADF){ /* FD went bad */ if(fd != mainFd){ close(fd); printf("FD:%d now closes\n",fd); } printf("Bad FD removed\n"); dist_deleteFd(o,fd); } if(msg.msg_flags & MSG_EOR){ if(dataout != NULL) goto deliverIt; } return(0); } big_o = o; if (msg.msg_flags & MSG_NOTIFICATION) { handle_notification(fd,readBuffer); return(0); } msgout.takeOk = 0; msgout.protocolId = 0; lastStream = msgout.streamNo = 0; lastStreamSeq = msgout.streamSeq = 0; if((dataout == NULL) && (msg.msg_flags & MSG_EOR)){ if(o_info.sinfo_assoc_id){ msgout.protocolId = o_info.sinfo_ppid; lastStream = msgout.streamNo = o_info.sinfo_stream; lastStreamSeq = msgout.streamSeq = o_info.sinfo_ssn; }else{ printf("Gak! no info set with full msg\n"); } msgout.takeOk = 0; msgout.totSize = sz; msgout.totData = readBuffer; msgout.siz = sz; msgout.data = readBuffer; msgout.from = &from; msgout.type = PROTOCOL_Sctp; msgout.to = NULL; msgout.origFrom = NULL; msgout.origType = PROTOCOL_Unknown; msgout.sender = (void *)&mainFd; dist_sendmessage(o,&msgout); }else{ char *newout; if(sctp_verbose) { printf("PARTIAL DELIVERY OF %d bytes (dtsize:%d)\n", sz,dtsize); } newout = calloc(1,(sz + dtsize)); if(newout == NULL){ printf("Gak! I am out of memory? .. drop a message\n"); if(dataout) free(dataout); dataout = NULL; dtsize = 0; return(0); } if(dataout){ memcpy(newout,dataout,dtsize); } memcpy(&newout[dtsize],readBuffer,sz); dtsize += sz; if(dataout){ free(dataout); } dataout = newout; deliverIt: if(msg.msg_flags & MSG_EOR){ /* Ok we can deliver this guy now */ if(o_info.sinfo_assoc_id){ msgout.protocolId = o_info.sinfo_ppid; lastStream = msgout.streamNo = o_info.sinfo_stream; lastStreamSeq = msgout.streamSeq = o_info.sinfo_ssn; }else{ printf("Gak! no info set with msg delivery?\n"); } msgout.takeOk = 1; msgout.totSize = dtsize; msgout.totData = dataout; msgout.siz = dtsize; msgout.data = dataout; msgout.from = &from; msgout.type = PROTOCOL_Sctp; msgout.to = NULL; msgout.origFrom = NULL; msgout.origType = PROTOCOL_Unknown; msgout.sender = (void *)&mainFd; dist_sendmessage(o,&msgout); dataout = NULL; dtsize = 0; } } return(0); }