Integrate boost-asio with file descriptor based socket api from KDB+ - boost-asio

I'm relatively new to boost-asio and I'm wondering if it's possible to make it work with KDB+ api here.
I tried something like the below but it doesn't seem to work properly,
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#define KXVER 3
#include "kx/k.h"
using boost::asio::ip::tcp;
namespace posix = boost::asio::posix;
class Feedhandler
{
public:
Feedhandler(boost::asio::io_service &io_service) : m_qsvc(io_service) {
char host[] = "localhost";
int port = 6812;
m_fd = khpu(host, port, "user:pass");
m_qsvc.assign(m_fd);
start_operations();
K ret = k(m_fd, ".u.sub", ks(""), ks(""), (K)0);
}
void start_operations()
{
boost::asio::async_read(m_qsvc, boost::asio::null_buffers(),
boost::bind(&Feedhandler::handle_read, this, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_read(const boost::system::error_code& error, size_t size)
{
K data = k(m_fd,(S)0);
start_operations();
}
private:
int m_fd;
posix::stream_descriptor m_qsvc;
};
int main(int argc, char* argv[])
{
boost::asio::io_service io_service;
Feedhandler fh(io_service);
io_service.run();
return 0;
}
The handle_read method gets hit once and then subsequently there's no more call-backs.

Actually, it's better to use async_wait instead of async_read, like below,
m_qsvc.async_wait(boost::asio::posix::stream_descriptor::wait_read,
boost::bind(&Feedhandler::handle_read, this, boost::asio::placeholders::error) );

Related

How can I stop the program inside the a parent or a child process?

I have this piece of code that I developed just to address a problem that I have in another large program that I am developing.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <limits.h>
#include <string>
#include <iostream>
using namespace std;
void processLine (char []);
void readLine(char []);
const int LIMIT = 512;
int main(int argc, char *argv[])
{
char oneLine[LINE_MAX];
readLine(oneLine);
return 0;
}
void readLine(char line[])
{
processLine(line);
//Otherstuff
------------
}
void processLine(char line[])
{
pid_t process;
int child_status;
string input;
cout << "Input: ";
cin >> input;
process = fork();
if(process == 0)
{ // do nothing
}
else
{
//parent
if(input == "quit")
{
printf("Quit command found ! \nExiting ");
for(int i = 0;i < 3;i++)
{
printf(".");
fflush(stdout);
sleep(1);
}
printf("\n");
exit(0);
}
else
{
wait(&child_status);
}
}
}
My goal is simple, When the user enter quit.
I will just display
Quit command found
Exiting ...
And there is a delay of one second between each of these three dots.
However the output that I get is
Quit command found
Exiting . other stuff ..
However, what seems to happen is that the parent process returns and then executes other stuff from the calling function before it continues to print the other two dots. How would I avoid the parent process from doing that ?
Use waitpid() like this:
pid_t childPid;
childPid = fork();
...
int returnStatus;
waitpid(childPid, &returnStatus, 0); // Parent process waits here for child to terminate.
Use it here
if(childPid == 0) // fork succeeded
{
// Do something
exit(0);
}
else // Main (parent) process after fork succeeds
{
int returnStatus;
waitpid(childPid, &returnStatus, 0);
}

Qt5 to stream two videos simultaneously

I created a GUI to play two videos from two cameras, one camera is a USB camera, and another one is integrated in my laptop. My code is simple, I have three files:
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QCamera>
#include <QCameraInfo>
#include <QCameraImageCapture>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QList <QCameraInfo> camList;
QCamera *camera1;
QCamera *camera2;
private slots:
void onCameraChanged(int);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
camera1 = NULL;
camera2 = NULL;
connect(ui->cameraComboBox,static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),this,
&MainWindow::onCameraChanged);
camList = QCameraInfo::availableCameras();
for(QList <QCameraInfo>::iterator it = camList.begin();it!=camList.end();++it) {
ui->cameraComboBox->addItem(it->description());
}
}
MainWindow::~MainWindow() {
delete ui;
}
void MainWindow::onCameraChanged(int idx) {
if(camera1 != NULL) {
camera1->stop();
}
qDebug() << idx;
camera1 = new QCamera(camList.at(idx),this);
camera1->setViewfinder(ui->mainView);
camera1->setCaptureMode(QCamera::CaptureStillImage);
camera1->start();
if(camera2 != NULL) {
camera2->stop();
}
camera2 = new QCamera(camList.at(idx+1),this);
camera2->setViewfinder(ui->submainView);
camera2->setCaptureMode(QCamera::CaptureStillImage);
camera2->start();
}
I have deleted irrelevant code. Of course I have this in the *.pro file:
QT += multimedia multimediawidgets
My code compiles correctly, but it can only stream one video (camera1), and the other one shows nothing. The error I got is
CameraBin error: "Error starting streaming on device '/dev/video1'."
CameraBin error: "Could not negotiate format"
Any help will be appreciated.

Is it possible to get list of files in directory using apache portable runtime?

I need to get list of files in directory using APR. How can I do it?
I was looking for answer in documentation, but found nothing.
Thanks!
The function you want is apr_dir_open. I found the header files to be the best documentation for APR
http://apr.apache.org/docs/apr/1.4/group_apr_dir.html
Here is an example for reading "." and reporting errors if any were encountered
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <apr.h>
#include <apr_errno.h>
#include <apr_pools.h>
#include <apr_file_info.h>
static void apr_fatal(apr_status_t rv);
int main(void)
{
apr_pool_t *pool;
apr_status_t rv;
// Initialize APR and pool
apr_initialize();
if ((rv = apr_pool_create(&pool, NULL)) != APR_SUCCESS) {
apr_fatal(rv);
}
// Open the directory
apr_dir_t *dir;
if ((rv = apr_dir_open(&dir, ".", pool)) != APR_SUCCESS) {
apr_fatal(rv);
}
// Read the directory
apr_finfo_t finfo;
apr_int32_t wanted = APR_FINFO_NAME | APR_FINFO_SIZE;
while ((rv = apr_dir_read(&finfo, wanted, dir)) == APR_SUCCESS) {
printf("%s\t%10"PRIu64"\n", finfo.name, (uint64_t)finfo.size);
}
if (!APR_STATUS_IS_ENOENT(rv)) {
apr_fatal(rv);
}
// Clean up
apr_dir_close(dir);
apr_pool_destroy(pool);
apr_terminate();
return 0;
}
static void apr_fatal(apr_status_t rv)
{
const int bufsize = 1000;
char buf[bufsize+1];
printf("APR Error %d: %s\n", rv, apr_strerror(rv, buf, bufsize));
exit(1);
}

boost multi_index_container serialization

I am trying to use the boost::multi_index_container with the boost::serialization. However when I use Pointer to objects as elements and a non_unique order, I get a memory access violation loading the serialized container. I find it interesting that the error doesn't occur for unique ordering or using objects instead of pointers as container elements.
Can somebody tell me if there is a problem with my code or if this is a bug in the boost library?
Here is a minimal example that produces the described error:
#include <boost/multi_index_container.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/set.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <fstream>
using namespace std;
using namespace boost::multi_index;
struct element {
friend class boost::serialization::access;
std::string member1;
element( int num ) { member1 = boost::lexical_cast<string>( num ); }
element() {}
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & member1;
}
};
int main( int argc, const char *argv[] )
{
typedef multi_index_container<element *, indexed_by<ordered_non_unique<member<element, std::string, &element::member1>>>> TestSet;
TestSet myset;
srand( time (NULL ));
for (int i = 0; i < 20; i++) {
myset.insert(new element(rand()));
}
// Write set
ofstream os("test.bin");
boost::archive::binary_oarchive boa(os);
boa << myset;
os.close();
// Read set
TestSet newset;
ifstream is("test.bin");
boost::archive::binary_iarchive bia(is);
bia >> newset;
return 0;
}
ofstream os("test.bin"); should be:
ofstream os("test.bin", ios::binary);
Also:
ifstream is("test.bin"); should be: ifstream is("test.bin", ios::binary);

simple linux device driver open call crash

I am trying to learn how to write a device driver in linux, following some reference from google and ldd3. i am able to insert the module below but when i tried to open the device in an application the kernel crashed.
The code and build steps followed as below :
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/ioport.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/param.h>
#include <linux/fs.h>
/* =============== Constant Definitions ============ */
#define SERIAL_IRQ 4
/* =============== Variable Definitions ============ */
static int SER_MAJOR = 0;
int ser_open(struct inode *inode, struct file *filp);
int ser_release(struct inode *inode, struct file *filp);
irqreturn_t my_ser_dev_isr(int irq,void *ser_data,struct pt_regs * pt_reg_var)
{
printk("\n\n ------- INTR raised -----------\n\n");
return 0;
}
int ser_open(struct inode *inode, struct file *filp)
{
if(request_irq(SERIAL_IRQ,&my_ser_dev_isr,1,"my_ser_dev_intr",NULL))
{
printk("\n interrupt req failed\n");
}
else
{
enable_irq(SERIAL_IRQ);
printk("\n!!!! ..obtained the requested interrupt and enabled\n");
}
}
int ser_release(struct inode *inode, struct file *filp)
{
disable_irq(SERIAL_IRQ);
free_irq(SERIAL_IRQ,NULL) ;
}
static struct file_operations ser_fops = {
open: ser_open,
release: ser_release
};
void *p = NULL;
irqreturn_t my_ser_dev_isr (int, void *, struct pt_regs *);
static int __init hello_start(void)
{
int ret_val=-1;
int result;
printk(KERN_INFO "Loading hello module...\n");
printk(KERN_INFO "Hello world\n");
result = register_chrdev(SER_MAJOR,"SER_DEV",&ser_fops);
if(result < 0)
{
printk(KERN_WARNING"Can't get major %d\n",SER_MAJOR);
return result;
}
if(SER_MAJOR == 0)
{
SER_MAJOR = result;
printk("SER DEV Major Number : %d",SER_MAJOR );
}
return 0;
}
static void __exit hello_end(void)
{
// free_irq(SERIAL_IRQ,NULL);
//release_region(0x0031,1);
printk(KERN_INFO "Goodbye Mr.\n");
}
module_init(hello_start);
module_exit(hello_end);
Makefile for module :
obj-m := hello.o
default:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
The application used for accesing is as follows :
#include <stdio.h> /* test.c */
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
static int dev;
int main(void)
{
char buff[40];
dev = open("/dev/my_ser_dev",O_RDONLY);
if(dev < 0)
{
printf( "Device Open ERROR!\n");
exit(1);
}
printf("Please push the GPIO_16 port!\n");
//read(dev,buff,40);
// scanf("%s",buff);
printf("%s\n",buff);
close(dev);
return 0;
}
insmod gave
[ 3837.312140] Loading hello module...
[ 3837.312147] Hello world
[ 3837.312218] SER DEV Major Number : 251
Then I created the special file using mknod /dev/my_ser_dev c 251 0
Executing the application caused kernel crash. I am using UBUNTU 3.2.0-23-generic-pae.
The function you are registering as your IRQ handler has the wrong prototype - it should be like
irqreturn_t irq_handler(int, void *);
Maybe you are referring to old documentation.