I need to program asynchronous ODBC driver,which need to handle user requested ODBC APIs in asynchronous way. I am desperate to know how to write an asynchronous program portable on all platforms.
Can you please provide me a basic C code on how to right asynchronous code?
Thanks in advance.
tidy code for asynchronous IO is a good thread to start in.
Portable solutions don't really exist. It also differs for socket streams and files, on all platforms.
libevent is a good abstraction.
Writing ODBC is not for the faint hearted.
Take below as example, notice async mostly used in multi-thread,
// FILE NAME: a.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
typedef void (*pcb)(int a);
typedef struct parameter
{
int a;
pcb callback;
} parameter;
void *callback_thread(void *p1)
{
//do something
parameter *p = (parameter *)p1;
while (1)
{
printf("GetCallBack print! \n");
sleep(3); //delay 3s
p->callback(p->a);
}
}
extern int SetCallBackFun(int a, pcb callback)
{
printf("SetCallBackFun print! \n");
parameter *p = malloc(sizeof(parameter));
p->a = 10;
p->callback = callback;
pthread_t thing1;
pthread_create(&thing1, NULL, callback_thread, (void *)p);
pthread_join(thing1, NULL);
}
// FILE NAME: b.c
#include "boo.c"
#include <stdio.h>
void fCallBack(int a)
{
//do something
printf("a = %d\n",a);
printf("fCallBack print! \n");
}
int main(void)
{
SetCallBackFun(4,fCallBack);
return 0;
}
Output is below,
SetCallBackFun print!
GetCallBack print!
a = 10
fCallBack print!
GetCallBack print!
a = 10
fCallBack print!
GetCallBack print!
a = 10
fCallBack print!
GetCallBack print!
a = 10
fCallBack print!
GetCallBack print!
a = 10
fCallBack print!
GetCallBack print!
...
In terms of calling function, there are three types: sync, back, and async.
The tricky thing is the last two are highly correlated, why is that?
Perhaps a graph would make it clear, i.e.
Related
Suppose some kernel (a __global__ function named foo) is running on a CUDA device. And suppose that kernel calls a __device__ function bar which is sometimes called from other kernels, i.e. the code of bar does not know at compile-time whether the kernel is foo or something else.
Can a thread running foo, within bar, obtain either the name "foo", the signature, or some other identifier of the kernel, preferable a human-readable one?
If necessary, assume the code has been compiled with any of --debug, --device-debug and/or --lineinfo.
The kernel can read the special register %gridid. %gridid is unique per launch. If performance then a simple kernel prolog can have one thread from each kernel launch output the gridid global function map using func and %gridid. Alternatively, the CUPTI SDK Activity API can be used to collect this information. The CUpti_ActivityKernel2 event contains per launch meta-data including the gridId and CUfunction name.
Here is an example reading %gridid.
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <stdint.h>
cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size);
static __device__ __inline__ uint64_t __gridid()
{
uint64_t gridid;
asm volatile("mov.u64 %0, %%gridid;" : "=l"(gridid));
return gridid;
}
__device__ void devPrintName()
{
static const char* name = __func__;
printf("%llu %s\n", __gridid(), name);
}
__global__ void globPrintName()
{
static const char* name = __func__;
printf("%llu %s\n", __gridid(), name);
devPrintName();
}
int main()
{
for (int i = 0; i < 4; ++i)
{
globPrintName<<<1,1,0>>>();
cudaDeviceReset();
}
return 0;
}
This sample outputs
1 globPrintName
1 devPrintName
2 globPrintName
2 devPrintName
3 globPrintName
3 devPrintName
4 globPrintName
4 devPrintName
I've got an application where I will be using a standalone C programming to read a CAN bus port with a socket. The user interface on this is Qt/QML code. I would like to use a non-blocking approach to call the bin program and either return nothing or return a string of the CAN packet.
The application will be low speed (just monitoring key presses, etc) so speed is not an issue. The current approach involves writing data from the socket program to a file, then having ANOTHER C program take the file and echo the string back to QML. UGH! Seems very messy. A simple Go/NoGo call would be easier. Here's the code I've got so far.
Thanks for any comments.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/can.h>
#include <linux/can/raw.h>
// Returns 0 if no errors, > 0 if errors found
int main(void) {
struct ifreq ifr;
struct can_frame frame;
struct sockaddr_can addr;
int s; // CAN socket descriptor
int nbytes; // Number of bytes read from CAN socket
char run_daemon = 0; // Set to 1 to run as a daemon process
char show_errors = 0; // Set to 1 to print errors
char *ifname = "can0"; // Define the CAN driver for use
if (run_daemon) // Skip the daemon call if not enabled
daemon(1,1);
if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
if (show_errors)
perror("Error while opening RAW socket");
return 1;
}
strcpy (ifr.ifr_name, ifname);
ioctl(s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
if (show_errors)
perror("Error in socket bind");
return 2;
}
// Loop here for daemon process
while (1) {
// Read CAN frame data
nbytes = read(s, &frame, sizeof(struct can_frame));
// If data is ready, process it
if (nbytes > 0) {
// Print all relevent frame data to QML
printf("%d ",frame.can_id);
printf("%d ",frame.can_dlc);
if(frame.can_dlc>0) printf("%d ",frame.data[0]);
if(frame.can_dlc>1) printf("%d ",frame.data[1]);
if(frame.can_dlc>2) printf("%d ",frame.data[2]);
if(frame.can_dlc>3) printf("%d ",frame.data[3]);
if(frame.can_dlc>4) printf("%d ",frame.data[4]);
if(frame.can_dlc>5) printf("%d ",frame.data[5]);
if(frame.can_dlc>6) printf("%d ",frame.data[6]);
if(frame.can_dlc>7) printf("%d ",frame.data[7]);
printf("\n");
}
if (!run_daemon) { // Exit if daemon is not running
close(s); // Close the CAN socket
return 0;
}
}
return 0; // Should never get here !!!
}
In the below code scanf() is working for getting the name from the user but fgets() is not working pls someone help me to understand why it's not working
#include <stdio.h>
#include <stdlib.h>
typedef struct university{
int roll_no;
char name[16];
}uni;
int main()
{
uni *ptr[5],soome;char i,j=0;
for(i=0;i<5;i++)
{
ptr[i]=(uni*)calloc(1,20);
if(ptr[i]==NULL)
{
printf("memory allocation failure");
}
printf("enter the roll no and name \n");
printf("ur going to enter at the address%u \n",ptr[i]);
scanf("%d",&ptr[i]->roll_no);
//scanf("%s",&ptr[i]->name);
fgets(&ptr[i]->name,16,stdin);
}
while(*(ptr+j))
{
printf("%d %s\n",ptr[j]->roll_no,ptr[j]->name);
j++;
}
return 0;
}
First of all, fgets(char *s, int n, FILE *stream) takes three argument: a pointer s to the beginning of a character array, a count n, and an input stream.
In the original application you used the address operator & to get the pointer not to the first element of the name[16] array, but to something else (to use the address operator, you should have referenced the first char in the array: name[0]).
You use a lot of magic numbers in your application (e.g. 20 as the size of the uni struct). In my sample I'm using sizeof as much as possible.
Given that you use calloc, I've used the fact that the first parameter is the number of elements of size equal to the second parameter to preallocate all the five uni struct at once.
Final result is:
#include <stdio.h>
#include <stdlib.h>
#define NUM_ITEMS (5)
#define NAME_LENGTH (16)
typedef struct university{
int roll_no;
char name[NAME_LENGTH];
} uni;
int main()
{
uni *ptr;
int i;
ptr = (uni*)calloc(NUM_ITEMS, sizeof(uni));
if(NULL == ptr) {
printf("memory allocation failure");
return -1;
}
for(i=0; i<NUM_ITEMS; i++) {
printf("enter the roll no and name \n");
printf("You're going to enter at the address: 0x%X \n",(unsigned int)&ptr[i]);
scanf("%d",&ptr[i].roll_no);
fgets(ptr[i].name, NAME_LENGTH, stdin);
}
for(i=0; i<NUM_ITEMS; i++) {
printf("%d - %s",ptr[i].roll_no,ptr[i].name);
}
free(ptr);
return 0;
}
Note: I've added a call to free(ptr); to free the memory allocated by calloc at the end of the application and a different return code if it's not possible to allocate the memory.
Could anyone give some simple examples (function names are good) for reading text files line by line (binary is OK if text is really hard) in a FreeBSD kernel module, from a given directory?
Really appreciate your kind help.
Here's a sample kernel module that'll cat your /etc/motd on load:
// kernel module motd catter.
// Doug Luce doug#forephypodia.con.com
#include <sys/param.h>
#include <sys/vnode.h>
#include <sys/fcntl.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/sbuf.h>
static int catfile(const char *filename) {
struct sbuf *sb;
static char buf[128];
struct nameidata nd;
off_t ofs;
ssize_t resid;
int error, flags, len;
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, curthread);
flags = FREAD;
error = vn_open(&nd, &flags, 0, NULL);
if (error)
return (error);
NDFREE(&nd, NDF_ONLY_PNBUF);
ofs = 0;
len = sizeof(buf) - 1;
sb = sbuf_new_auto();
while (1) {
error = vn_rdwr(UIO_READ, nd.ni_vp, buf, len, ofs,
UIO_SYSSPACE, IO_NODELOCKED, curthread->td_ucred,
NOCRED, &resid, curthread);
if (error)
break;
if (resid == len)
break;
buf[len - resid] = 0;
sbuf_printf(sb, "%s", buf);
ofs += len - resid;
}
VOP_UNLOCK(nd.ni_vp, 0);
vn_close(nd.ni_vp, FREAD, curthread->td_ucred, curthread);
uprintf("%s", sbuf_data(sb));
return 0;
}
static int EventHandler(struct module *inModule, int inEvent, void *inArg) {
switch (inEvent) {
case MOD_LOAD:
uprintf("MOTD module loading.\n");
if (catfile("/etc/motd") != 0)
uprintf("Error reading MOTD.\n");
return 0;
case MOD_UNLOAD:
uprintf("MOTD module unloading.\n");
return 0;
default:
return EOPNOTSUPP;
}
}
static moduledata_t moduleData = {
"motd_kmod",
EventHandler,
NULL
};
DECLARE_MODULE(motd_kmod, moduleData, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
This was cobbled together mostly from bits of https://svnweb.freebsd.org/base/release/10.1.0/sys/kern/vfs_mountroot.c?revision=274417&view=markup
There's no nice scanning/parsing facilities native kernel-side, so
that's usually done the hard way.
I have a client server program where client writes a command on PIPE for server. While reading the command from Server it reads only first char of command and throws error. Can anyone help me with this?
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <sys/wait.h>
#include <mqueue.h>
#include <sys/stat.h>
#include "Functions.h"
#define MSGBUFFER_SIZE 50000
pid_t serverPid;
pid_t clientPid;
typedef struct msgbuf {
int messageLength;
int messageType;
char messageText[MSGBUFFER_SIZE];
} Message_buf;
int writePIPE(int fd, Message_buf *inputMessage){
printf("\n In write pipe message length :%d",inputMessage->messageLength);
printf("\n In write pipe message Data :%s",inputMessage->messageText);
ssize_t n=write(fd,inputMessage,inputMessage->messageLength);
printf("\n Size :%d", n);
return n;
}
ssize_t readPIPE(int fd, Message_buf *outputMessage)
{
ssize_t len;
ssize_t n;
if((n=read(fd,outputMessage,sizeof(outputMessage)))==0)
{
printf("\n Error");
return 0;
}
if((len=outputMessage->messageLength)>0)
{
printf("\n Length ---->:%d",len);
if((n=read(fd,outputMessage->messageText,strlen(outputMessage->messageText)))!=len)
printf("\n ERRRRROR expected %d got %d",len,n);
}
//printf("\n In Read PIPE: %s",outputMessage->messageText);
return len;
}
void Server(int readfd,int writefd)
{
Message_buf server_MessageBuf;
ssize_t length;
if((length=readPIPE(readfd,&server_MessageBuf))==0)
{
printf("\n End of file while reading pathname");
}
//server_MessageBuf.messageText[length]='\0';
printf("\n LENGTH :%d",server_MessageBuf.messageLength);
printf("\n Printing in server: %s\n",server_MessageBuf.messageText);
}
void Client(int readfd,int writefd)
{
char inputFileName[MAX_SIZE];
char inputOperation[MAX_SIZE];
char *cCommandInput = NULL;
char *fileOperation = NULL;
char *operation = (char *) malloc(MAX_SIZE);
int commandValidateStatus = 0;
int commandInterpretationStatus=0;
Message_buf client_MessageBuf;
for(;;)
{
while(1)
{
cCommandInput = acceptInput();
fileOperation = (char *) malloc(sizeof(cCommandInput));
strcpy(fileOperation,cCommandInput);
/**Function call to determine operation read/delete/exit/invalid choice and filename*****/
commandInterpretationStatus = interpretCommand(cCommandInput,
inputOperation, inputFileName);
operation = inputOperation;
/**Function call to validate the input command******/
commandValidateStatus = validateCommand(
commandInterpretationStatus, inputOperation, inputFileName);
if(commandValidateStatus==-1)
{
printf("\n Invalid Operation");
}
/*Exit command entered***/
if (commandValidateStatus == 1)
{
/*Code to clear resources */
kill(serverPid,SIGKILL);
kill(clientPid,SIGKILL);
exit(0);
}
/***Read or Delete****/
if (commandValidateStatus == 2 || commandValidateStatus == 3)
{
printf("\n Read or Delete\n");
strcpy(client_MessageBuf.messageText,fileOperation);
client_MessageBuf.messageLength=strlen(fileOperation);
client_MessageBuf.messageType=1;
if((writePIPE(writefd,&client_MessageBuf))<0)
{
printf("\n Error writing on client side ");
}
//read(readfd,*client_MessageBuf,sizeof(client_MessageBuf));
//printf("\n Reding server responsed");
//printf("%s",client_MessageBuf.messageText);
}
}
}
}
int main()
{
int pipe1[2],pipe2[2];
pipe(pipe1);
pipe(pipe2);
pid_t pid;
pid=fork();
serverPid=pid;
if(pid==0)
{
/*Call Server*/
close(pipe1[1]);
close(pipe2[0]);
Server(pipe1[0], pipe2[1]);
}
else
{
close(pipe1[0]);
close(pipe2[1]);
Client(pipe2[0],pipe1[1]);
}
return 0;
}
It looks like the code writes and reads struct msgbuf incorrectly:
typedef struct msgbuf {
int messageLength;
int messageType;
char messageText[MSGBUFFER_SIZE];
} Message_buf;
// ...
strcpy(client_MessageBuf.messageText,fileOperation);
client_MessageBuf.messageLength=strlen(fileOperation);
client_MessageBuf.messageType=1;
if((writePIPE(writefd,&client_MessageBuf))<0)
// ....
int writePIPE(int fd, Message_buf *inputMessage){
printf("\n In write pipe message length :%d",inputMessage->messageLength);
printf("\n In write pipe message Data :%s",inputMessage->messageText);
ssize_t n=write(fd,inputMessage,inputMessage->messageLength);
printf("\n Size :%d", n);
return n;
}
The above pieces that write struct msgbuf only write the first messageLength bytes of the structure which doesn't include the length of messageLength and messageType members, i.e. it truncates the object.
When reading:
ssize_t readPIPE(int fd, Message_buf *outputMessage)
{
// ...
if((n=read(fd,outputMessage,sizeof(outputMessage)))==0)
It reads only sizeof(outputMessage) bytes, which is the size of the pointer, not the object. Even if you fix it by changing it to sizeof(*outputMessage) that won't do enough, since that would expect to read the complete object whereas the writing piece truncates the object.
A good start to fix it would be to split the message into two parts: header and payload. The header is a structure of a fixed size, e.g.:
typedef struct {
int messageType;
int payloadLength;
} MessageHeader;
The payload is a variable-length part following the header. This way it would first write the entire header object into the pipe followed by payloadLength bytes of payload. When reading it would first read again the entire header and then read exactly payloadLength bytes.
Also note, that read() and write() calls may read or write less then asked, so that case needs to be explicitly handled by keeping reading or writing until the exact number of bytes has been processed.