-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added some other aio tests. Small include fixes
- Loading branch information
Showing
9 changed files
with
271 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <aio.h> | ||
#include <stdlib.h> | ||
#include <fcntl.h> | ||
|
||
#define BUFSIZE 1024 | ||
|
||
int main(void) { | ||
int fd, ret; | ||
struct aiocb my_aiocb; | ||
|
||
fd = open("file.txt", O_RDONLY); | ||
if (fd < 0) | ||
perror("open"); | ||
|
||
bzero((char *) &my_aiocb, sizeof(struct aiocb)); | ||
|
||
my_aiocb.aio_buf = calloc(1, BUFSIZE + 1); | ||
if (!my_aiocb.aio_buf) | ||
perror("malloc"); | ||
|
||
my_aiocb.aio_fildes = fd; | ||
my_aiocb.aio_nbytes = BUFSIZE; | ||
my_aiocb.aio_offset = 0; | ||
|
||
ret = aio_read(&my_aiocb); | ||
if (ret < 0) | ||
perror("aio_read"); | ||
|
||
while (aio_error(&my_aiocb) == EINPROGRESS) | ||
continue; | ||
|
||
if ((ret = aio_return(&my_aiocb))) { | ||
printf("ret:%d,read:%s\n", ret, my_aiocb.aio_buf); | ||
} else { | ||
printf("read 0\n"); | ||
} | ||
|
||
|
||
close(fd); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
#include <aio.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <netdb.h> | ||
#include <string.h> | ||
#include <netinet/in.h> | ||
#include <sys/socket.h> | ||
#include <sys/types.h> | ||
#include <assert.h> | ||
#include <errno.h> | ||
#include <arpa/inet.h> | ||
|
||
#define BUFSIZE (100) | ||
|
||
#ifndef __amigaos4__ | ||
#define sigval_t __sigval_t | ||
#endif | ||
|
||
void aio_read_completion_handler(sigval_t sigval); | ||
void aio_write_completion_handler(sigval_t sigval); | ||
struct aiocb my_aiocb1, my_aiocb2; | ||
|
||
// Global variables | ||
struct aiocb *cblist[2]; | ||
int theSocket; | ||
|
||
void InitializeAiocbData(struct aiocb *pAiocb, char *pBuffer) { | ||
bzero((char *) pAiocb, sizeof(struct aiocb)); | ||
|
||
pAiocb->aio_fildes = theSocket; | ||
pAiocb->aio_nbytes = BUFSIZE; | ||
pAiocb->aio_offset = 0; | ||
pAiocb->aio_buf = pBuffer; | ||
} | ||
|
||
void IssueReadOperation(struct aiocb *pAiocb, char *pBuffer) { | ||
InitializeAiocbData(pAiocb, pBuffer); | ||
|
||
/* Link the AIO request with a thread callback */ | ||
pAiocb->aio_sigevent.sigev_notify = SIGEV_THREAD; | ||
pAiocb->aio_sigevent.sigev_notify_function = aio_read_completion_handler; | ||
pAiocb->aio_sigevent.sigev_notify_attributes = NULL; | ||
pAiocb->aio_sigevent.sigev_value.sival_ptr = &my_aiocb1; | ||
|
||
int ret = aio_read(pAiocb); | ||
assert(ret >= 0); | ||
} | ||
|
||
void IssueWriteOperation(struct aiocb *pAiocb, char *pBuffer) { | ||
InitializeAiocbData(pAiocb, pBuffer); | ||
|
||
/* Link the AIO request with a thread callback */ | ||
pAiocb->aio_sigevent.sigev_notify = SIGEV_THREAD; | ||
pAiocb->aio_sigevent.sigev_notify_function = aio_write_completion_handler; | ||
pAiocb->aio_sigevent.sigev_notify_attributes = NULL; | ||
pAiocb->aio_sigevent.sigev_value.sival_ptr = &my_aiocb2; | ||
|
||
int ret = aio_write(pAiocb); | ||
assert(ret >= 0); | ||
} | ||
|
||
void aio_write_completion_handler(sigval_t sigval) { | ||
struct aiocb *req; | ||
req = (struct aiocb *) sigval.sival_ptr; | ||
} | ||
|
||
void aio_read_completion_handler(sigval_t sigval) { | ||
struct aiocb *req; | ||
req = (struct aiocb *) sigval.sival_ptr; | ||
} | ||
|
||
int main() { | ||
int ret; | ||
int nPort = 11111; | ||
char *szServer = "102.168.0.204"; | ||
|
||
// Connect to the remote server | ||
theSocket = socket(AF_INET, SOCK_STREAM, 0); | ||
assert(theSocket >= 0); | ||
|
||
struct hostent *pServer; | ||
struct sockaddr_in serv_addr; | ||
pServer = gethostbyname(szServer); | ||
|
||
bzero((char *) &serv_addr, sizeof(serv_addr)); | ||
serv_addr.sin_family = AF_INET; | ||
serv_addr.sin_port = htons(nPort); | ||
bcopy((char *) pServer->h_addr, (char *) &serv_addr.sin_addr.s_addr, pServer->h_length); | ||
|
||
assert(connect(theSocket, (const struct sockaddr *) (&serv_addr), sizeof(serv_addr)) >= 0); | ||
|
||
// Construct the AIO callbacks array | ||
char *pBuffer = malloc(BUFSIZE + 1); | ||
|
||
bzero((char *) cblist, sizeof(cblist)); | ||
cblist[0] = &my_aiocb1; | ||
cblist[1] = &my_aiocb2; | ||
|
||
// Start the read and write operations on the same socket | ||
IssueReadOperation(&my_aiocb1, pBuffer); | ||
IssueWriteOperation(&my_aiocb2, pBuffer); | ||
|
||
// Wait for I/O completion on both operations | ||
int nRound = 1; | ||
printf("\naio_suspend round #%d:\n", nRound++); | ||
ret = aio_suspend(cblist, 2, NULL); | ||
assert(ret == 0); | ||
|
||
// Check the error status for the read and write operations | ||
ret = aio_error(&my_aiocb1); | ||
assert(ret == EWOULDBLOCK); | ||
|
||
// Get the return code for the read | ||
{ | ||
ssize_t retcode = aio_return(&my_aiocb1); | ||
printf("First read operation results: aio_error=%d, aio_return=%d - That's the first EWOULDBLOCK\n", ret, retcode); | ||
} | ||
|
||
ret = aio_error(&my_aiocb2); | ||
assert(ret == EINPROGRESS); | ||
printf("Write operation is still \"in progress\"\n"); | ||
|
||
// Re-issue the read operation | ||
IssueReadOperation(&my_aiocb1, pBuffer); | ||
|
||
// Wait for I/O completion on both operations | ||
printf("\naio_suspend round #%d:\n", nRound++); | ||
ret = aio_suspend(cblist, 2, NULL); | ||
assert(ret == 0); | ||
|
||
// Check the error status for the read and write operations for the second time | ||
ret = aio_error(&my_aiocb1); | ||
assert(ret == EINPROGRESS); | ||
printf("Second read operation request is suddenly marked as \"in progress\"\n"); | ||
|
||
ret = aio_error(&my_aiocb2); | ||
assert(ret == 0); | ||
|
||
// Get the return code for the write | ||
{ | ||
ssize_t retcode = aio_return(&my_aiocb2); | ||
printf("Write operation has completed with results: aio_error=%d, aio_return=%d\n", ret, retcode); | ||
} | ||
|
||
// Now try waiting for the read operation to complete - it'll just busy-wait, receiving "EWOULDBLOCK" indefinitely | ||
do { | ||
printf("\naio_suspend round #%d:\n", nRound++); | ||
ret = aio_suspend(cblist, 1, NULL); | ||
assert(ret == 0); | ||
|
||
// Check the error of the read operation and re-issue if needed | ||
ret = aio_error(&my_aiocb1); | ||
if (ret == EWOULDBLOCK) { | ||
IssueReadOperation(&my_aiocb1, pBuffer); | ||
printf("EWOULDBLOCK again on the read operation!\n"); | ||
} | ||
} while (ret == EWOULDBLOCK); | ||
|
||
free(pBuffer); | ||
|
||
return 0; | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#include <aio.h> | ||
#include <stdio.h> | ||
|
||
char CONTENT[] = "asdf;"; | ||
const int LENGTH = 5; | ||
|
||
struct aiocb createIoRequest(int fd, off_t offset, volatile void *content, size_t length) { | ||
// create and initialize the aiocb structure. | ||
// If we don't init to 0, we have undefined behavior. | ||
// E.g. through sigevent op.aio_sigevent there could be | ||
// a callback function being set, that the program | ||
// tries to call - which will then fail. | ||
struct aiocb ret = {0}; | ||
{ | ||
ret.aio_fildes = fd; | ||
ret.aio_offset = offset; | ||
ret.aio_buf = content; | ||
ret.aio_nbytes = length; | ||
} | ||
return ret; | ||
} | ||
|
||
|
||
int main() { | ||
FILE *file = fopen("RAM:outfile.txt", "w"); | ||
int fd = fileno(file); | ||
|
||
struct aiocb op = createIoRequest(fd, 0, CONTENT, LENGTH); | ||
struct aiocb op2 = createIoRequest(fd, LENGTH, CONTENT, LENGTH); | ||
|
||
// schedule write | ||
// for valgrind mem leak output see comments from answer in | ||
// https://stackoverflow.com/questions/4248720/aio-h-aio-read-and-write-memory-leak | ||
int ret = aio_write(&op); | ||
printf("aio_write 1: %d\n", ret); | ||
ret = aio_write(&op2); | ||
printf("aio_write 2: %d\n", ret); | ||
|
||
// wait until everything is done | ||
|
||
const int OPs = 2; | ||
const struct aiocb *aiolist[OPs]; | ||
aiolist[0] = &op; | ||
aiolist[1] = &op2; | ||
|
||
ret = aio_suspend(aiolist, OPs, NULL); | ||
printf("aio_suspend: %d\n", ret); | ||
|
||
// report possible errors | ||
ret = aio_error(&op); | ||
printf("errno 1: %d\n", ret); | ||
ret = aio_error(&op2); | ||
printf("errno 2: %d\n", ret); | ||
// error codes can be checked in <errno.h> | ||
|
||
fclose(file); | ||
|
||
return 0; | ||
} |