The sound output functions are giving me unexpected messages. Is this a sign I'm doing something wrong? If so what? Otherwise is there a good source that explains what these messages might be?
waveOutOpen() gives me message 955 MM_WOM_OPEN as documented, followed by an undocumented 1024 (possibly DDM_SETFMT, DM_GETDEFID, NIN_SELECT, TBM_GETPOS, WM_PSD_PAGESETUPDLG, WM_USER, according to https://wiki.winehq.org/List_Of_Windows_Messages).
In main thread:
hAudioOut = CreateThread( 0, 0, AudioOutThreadProc, this, 0, &dwAudioOutId );
if( !hAudioOut ) {
AKS( AKSWarn, "Audio Out CreateThread() fail" );
return;
}
In the resulting audio thread:
static DWORD WINAPI AudioOutThreadProc( LPVOID lpParameter ) {
Interpreter* pinterp = (Interpreter *) lpParameter;
WAVEFORMATEX waveFormat;
waveFormat.cbSize = sizeof(waveFormat);
waveFormat.wFormatTag = WAVE_FORMAT_PCM;
waveFormat.nChannels = 1;
waveFormat.nSamplesPerSec = (int) dFreqEval;
waveFormat.wBitsPerSample = iOutputBits;
waveFormat.nBlockAlign = waveFormat.nChannels *
waveFormat.wBitsPerSample / 8;
waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec *
waveFormat.nBlockAlign;
MMRESULT openRes = waveOutOpen( &waveOut, WAVE_MAPPER, &waveFormat,
(DWORD_PTR) dwAudioOutId, (DWORD_PTR) this,
CALLBACK_THREAD /*| WAVE_FORMAT_DIRECT*/ );
if ( openRes != MMSYSERR_NOERROR )
Log( "waveOutOpen() = %d", openRes );
MSG msg;
int iRV;
while ( iRV = GetMessage( &msg, 0, 0, 0 ) ) {
Log( "got message %d", msg.message );
// Is the main thread asking us to stop?
if ( pinterp->bStop ) {
Log( "AudioInThreadProc(): bStop" );
return EXIT_SUCCESS;
}
// Did we get an error?
if ( iRV == -1 ) {
Log( "GetMessage() = -1: %d", GetLastError() );
abort();
}
// Did we get an expected message? (Only one expected,
// which tells us its time to write more data.)
if ( msg.message == WOM_DONE )
pinterp->Write();
// Anything else--log it.
else
Log( "got unknown message %d", msg.message );
}
Log( "AudioInThreadProc(): GetMessage = return" );
return msg.wParam;
}
waveOutWrite() isn't documented to give any messages, but is giving me message 1024 as well.
Related
I'm trying to check if a file on a jffs2 fs exist from a kernel space. I have a Barrier Breaker OpenWrt with a 3.10.14 Linux kernel. (There's an MTD subsystem in use, so I have pseudo block devices for partitions on a NAND flash (/dev/mtdblock1, ...12).)
(I'm implementing some upgrading logic which requires keeping some state between reboots, to store this state, I use the file.)
To check a file existence I just try to open the file (without an O_CREAT flag) and make a decision based on a result of opening. I use the next article about opening a file from within kernel: Read/write files within a Linux kernel module.
I'm able to check a file existence using this approach, but this file is placed not on a rootfs partition, so I have to mount that partition before I can open the file on it.
I'm able to mount the partition, open file (to check it existence) and close it, if it was opened, but failed to un-mount it: I got an error -16: EBUSY which, as I guess, means that someone else keep using this block device/mount point. So a question who can keep a reference on it?
I think it's a bad idea, but just to test, I tried to un-mount forcibly with an MNT_FORCE, but, as this article https://linux.die.net/man/2/umount states that this option only for NFS fs, nothing changed.
Here's a code:
/* lool at https://stackoverflow.com/questions/1184274/read-write-files-within-a-linux-kernel-module */
static struct file *file_open( const char *path, int flags, int rights )
{
struct file *filp = NULL;
mm_segment_t oldfs;
int err = 0;
oldfs = get_fs();
set_fs( get_ds() );
filp = filp_open( path, flags, rights );
set_fs( oldfs );
if( IS_ERR( filp ) )
{
err = PTR_ERR( filp );
return NULL;
}
return filp;
}
bool need_to_switch_to_me_upgrade_mode( void )
{
struct file* me_upgrade_finished_file;
dev_t me_upgrade_dev;
char full_name[256] = { 0 };
bool result;
int err;
const char* me_upgrade_dir = "/me_upgrade";
const char* me_upgrade_dev_name = "/dev/me_upgrade";
const char* me_upgrade_finished_flag = "/etc/me_upgrade_finished";
// /dev/mtdblock6
const char* me_upgrade_finished_flag_partition = "/dev/mtdblock" str( RECOVERY_ROOTFS_DATA_MTD_PART_NUM );
err = sys_mkdir( (const char __user __force *) me_upgrade_dir, 0700 );
if( err < 0 )
panic( "fail to mkdir %s\n", me_upgrade_dir );
me_upgrade_dev = name_to_dev_t( me_upgrade_finished_flag_partition );
err = create_dev( me_upgrade_dev_name, me_upgrade_dev );
if( err < 0 )
panic( "fail to create_dev %s\n", me_upgrade_dev_name );
err = sys_mount( me_upgrade_dev_name, me_upgrade_dir, "jffs2", MS_SILENT, NULL );
if( err < 0 )
panic( "fail to mount %s on to %s, err: %d\n", me_upgrade_dev_name, me_upgrade_dir, err );
strlcat( full_name, me_upgrade_dir, sizeof( full_name ) );
strlcat( full_name, me_upgrade_finished_flag, sizeof( full_name ) );
me_upgrade_finished_file = file_open( full_name, O_RDONLY, 0 );
if( !me_upgrade_finished_file )
{
printk( "fail to open a %s file\n", full_name );
result = true;
}
else
{
printk( "success to open a file\n" );
result = false;
}
if( me_upgrade_finished_file )
{
err = filp_close( me_upgrade_finished_file, NULL );
printk( "filp_close returned: %d\n", err );
}
err = sys_umount( me_upgrade_dir, MNT_DETACH );
printk( "sys_umount returned: %d\n", err );
sys_unlink( me_upgrade_dev_name ); // destroy_dev( me_upgrade_dev_name );
sys_rmdir( me_upgrade_dir );
return result;
}
This code is called from a kernel_init_freeable function (init/main.c) after we have MTD subsystem initialized (after do_basic_setup() and before a rootfs gets mounted).
So the questions are:
who can keep using a block device/mount point after I closed a file?
is any other ways to check if file exist from within kernel?
I have a second option, just to place my state in a partition without any fs, and check it by performing a raw access to the flash memory, but this approach will require significant changes to user code I have now, so I'm trying to avoid it...
P.S. I tried to change a call to file_open/filp_close by sys_open/sys_close (with the same arguments), but nothing changed...
I try using CreateCopy(), it seem in thrown me an exception when i run the program
Unhandled exception at 0x000007FEDF2C9120 (gdal202.dll) in GdalTest.exe: 0xC0000005: Access violation reading location 0x0000000000000058.
It will display this output on the console:
I try debug on the exception occurs, on the call stack it will go to the new tab then display no symbol loaded
I hope someone can explain to me what file not be loaded and if the console can view raster map it is will throw an error or exception ?
Below is my code if someone want to copy and make reference it just i have issues on "Using CreateCopy()" part.
Thank you and best regards,
// GdalTest.cpp : Defines the entry point for the console application.
//
#include "cpl_conv.h" // for CPLMalloc()
#include "stdafx.h"
#include "gdal.h"
#include <stdlib.h>
#include <stdio.h>
#include "iostream"
#include "cpl_string.h"
#include "gdal_priv.h"
class GDALMajorObject;
class GDALDataset;
class GDALRasterBand;
class GDALDriver;
class GDALRasterAttributeTable;
class GDALProxyDataset;
class GDALProxyRasterBand;
class GDALAsyncReader;
int main(int argc,char* argv)
{
///*/*/*/*/*/*/*/*/*/*Getting Dataset Information*/*/*/*/*/*/*/*/*/*/
GDALDataset *poDataset;
//GDALDatasetH *poDatasetH;
const char* Raster = new char[256];
double adfGeoTransform[6];
GDALAllRegister();
Raster = "C:\\Users\\User\\Desktop\\DSI REFERENCE\\Map Data\\Raster\\4257.tif";
poDataset = (GDALDataset *) GDALOpen(Raster, GA_ReadOnly )CPL_WARN_UNUSED_RESULT;
//poDataset = (GDALDataset *) GDALOpen(Raster, GA_ReadOnly );
if( poDataset == NULL )
{
printf("Not found");
}
else
{
printf( "Driver: %s/%s\n",
poDataset->GetDriver()->GetDescription(),
poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) );
printf( "Size is %dx%dx%d\n",
poDataset->GetRasterXSize(), poDataset->GetRasterYSize(),
poDataset->GetRasterCount() );
if( poDataset->GetProjectionRef() != NULL )
printf( "Projection is `%s'\n", poDataset->GetProjectionRef() );
if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None )
{
printf( "Origin = (%.6f,%.6f)\n",
adfGeoTransform[0], adfGeoTransform[3] );
printf( "Pixel Size = (%.6f,%.6f)\n",
adfGeoTransform[1], adfGeoTransform[5] );
}
}
///*/*/*/*/*/*/*/*/*/* Fetching a Raster Band*/*/*/*/*/*/*/*/*/*/
GDALRasterBand *poBand;
int nBlockXSize, nBlockYSize;
int bGotMin, bGotMax;
double adfMinMax[2];
poBand = poDataset->GetRasterBand( 1 );
poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
printf( "Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize,GDALGetDataTypeName(poBand->GetRasterDataType()),
GDALGetColorInterpretationName( poBand->GetColorInterpretation()) );
adfMinMax[0] = poBand->GetMinimum( &bGotMin );
adfMinMax[1] = poBand->GetMaximum( &bGotMax );
if( ! (bGotMin && bGotMax) )
GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);
printf( "Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1] );
if( poBand->GetOverviewCount() > 0 )
printf( "Band has %d overviews.\n", poBand->GetOverviewCount() );
if( poBand->GetColorTable() != NULL )
printf( "Band has a color table with %d entries.\n",
poBand->GetColorTable()->GetColorEntryCount() );
// make it 256 bytes for a string length of 255 plus null (\0) terminator
///*/*/*/*/*/*/*/*/*/*/*Reading Raster Data*/*/*/*/*/*/*/*/*/*/*/
float *pafScanline;
int nXSize = poBand->GetXSize();
pafScanline = (float *) CPLMalloc(sizeof(float)*nXSize);
poBand->RasterIO( GF_Read, 0, 0, nXSize, 1,pafScanline, nXSize, 1, GDT_Float32,0, 0 );
///*/*/*/*/*/*/*/*/*/*/*Techniques for Creating Files (determine whether it supports Create() and/or CreateCopy().) */*/*/*/*/*/*/*/*/*/*/
const char *pszFormat = "GTiff";
GDALDriver *poDriver;
char **papszMetadata;
poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
if( poDriver == NULL )
exit( 1 );
papszMetadata = poDriver->GetMetadata();
if( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATE, FALSE ) )
printf( "Driver %s supports Create() method.\n", pszFormat );
if( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATECOPY, FALSE ) )
printf( "Driver %s supports CreateCopy() method.\n", pszFormat );
///*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*Using CreateCopy()*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
const char*pszDstFilename= new char[256];
GDALDataset *poSrcDS =(GDALDataset *) GDALOpen( pszDstFilename, GA_ReadOnly );
GDALDataset *poDstDS;
poDstDS = poDriver->CreateCopy( pszDstFilename, poSrcDS, FALSE,NULL, NULL, NULL );
/* Once we're done, close properly the dataset */
if( poDstDS != NULL )
GDALClose( (GDALDatasetH) poDstDS );
GDALClose( (GDALDatasetH) poSrcDS );
std::cin.get();
//delete[] Raster;// release the memory VERY IMPORTANT
}
You haven't set the variable pszDstFilename to anything meaningful. You allocated it, but it just contains random junk. You need to put a valid existing dataset into it for anything useful to happen in the call to GDALOpen(). The documentation states:
Once the drivers are registered, the application should call the free standing GDALOpen() function to open a dataset, passing the name of the dataset and the access desired (GA_ReadOnly or GA_Update).
In an MFC application that has to process user events in real time, a sub-thread is created to do some lengthy math processing. However, sending it a message results in error 1159, which winerror.h reveals to be ERROR_MESSAGE_SYNC_ONLY. Why?
Thread creation:
#define MATHTHREAD_PROC ( 1 )
hMathThread = CreateThread( 0, 0, MathThreadProc, this, 0, &dwMathThreadID );
if( !hMathThread )
printf( "Math CreateThread() fail\n" );
Thread signalling:
if ( !PostThreadMessage( dwMathThreadID, MATHTHREAD_PROC, NULL, 0 ) ) {
DWORD dwError = GetLastError();
printf( "PostThreadMessage() for math thread: %d\n", dwError );
}
Thread code:
static DWORD WINAPI MathThreadProc( LPVOID pvUserData ) {
return ( (MyClass*) pvUserData )->MathThread();
}
DWORD MyClass::MathThread() {
MSG msg;
int iRV;
// https://msdn.microsoft.com/en-us/library/ms644946(v=vs.85).aspx
iRV = PeekMessage( &msg, NULL, WM_USER, WM_USER, PM_NOREMOVE );
while ( iRV = GetMessage( &msg, 0, 0, 0 ) ) {
if ( iRV == -1 )
printf( "GetMessage() = -1: %d\n", GetLastError() );
switch ( msg.message ) {
case MATHTHREAD_PROC:
ProcessMath();
break;
default:
printf( "got math thread exit request %p\n", this );
abort();
}
}
printf( "SCGraph::MathThread(): GetMessage = WM_QUIT\n" );
return msg.wParam;
}
ERROR_MESSAGE_SYNC_ONLY means that the message is below WM_USER. Just changing the message ID causes the post to work:
#define MATHTHREAD_PROC ( WM_USER + 1 )
I have a server that spawns a thread for each client that connects to it. The thread then deals with receiving/sending data to the client. Here is my server code:
//////////////
// START //
/////////////
while( 1 )
{
if( listen(serverSocket, SOMAXCONN) == SOCKET_ERROR )
{
printf( "Listen failed with error: %ld\n", WSAGetLastError() );
break;
}
/*
* wait for clients...
*/
clientSocket = accept(serverSocket,
(struct sockaddr *)&clientSockAddr,
&clientSockAddrLen);
if( clientSocket == INVALID_SOCKET )
{
printf("%d:accept failed\n", WSAGetLastError());
closesocket(serverSocket);
WSACleanup();
return 1;
}
printf("Client accepted: IP: %s PORT: %d\n",
inet_ntoa(clientSockAddr.sin_addr),
clientSockAddr.sin_port );
THREADDATA threadData = { clientSocket };
sprintf_s(threadData.ip, "%s", inet_ntoa(clientSockAddr.sin_addr));
// spawn a thread for each client
hthread = CreateThread(
NULL, // don't inherit handle
0, // use default size for the executable
processClient,
(pTHREADDATA)&threadData, // thread data
0, // run right away
&threadId );
}
And here is what my thread function looks like:
/*
called by thread for each client
*/
DWORD WINAPI processClient(LPVOID lpParam)
{
int numBytesRecvd = 0,
numBytesSent = 0,
index = 0,
nLeft = SIZE,
TOTAL = SIZE;
char buff[SIZE];
int run = 1;
char msg[MSG_SIZE];
pTHREADDATA td = (pTHREADDATA)lpParam;
/* keep processing client */
while (run)
{
memset(buff, 0, SIZE);
numBytesRecvd = recv(td->clientSocket, buff, nLeft, 0);
/* CLIENT EXITED */
if( !strcmp(buff, "exit") )
{
printf("Client exited!\n");
run = 0;
}
if( numBytesRecvd > 0 )
{
printf("< %s\n", buff);
}
if (numBytesRecvd == 0)
{
printf("Client closed!\n");
run = 0;
}
if( numBytesRecvd == SOCKET_ERROR )
{
printf("%d:Recieve error!\n", WSAGetLastError());
run = 0;
}
}
closesocket(td->clientSocket);
ExitThread(0);
return 0;
}
Issue:
So I start the server and the client, say client1 (from command prompt in win 7), everything is fine. When I type something at the client1 terminal, it is printed at the server terminal.
Now I launch another client, client2, it gets connected to the server and whatever I type gets displayed at the server, but now when I type something at client1 it doesn't get displayed at the server terminal.
So basically every time I start a new client, only that client can talk to the server, the old clients cannot!!! But I thought the thread will keep handling each client? Or is it that cmd prompt in windows is not thread safe?
I can see two probable issues here : 1) You are passing threadData on the stack to a different thread. You should be allocating it on the heap and then pass it to the thread. 2)I think you are not assigning clientSocket correctly to threadData, shouldnt you be assigning to a member of the structure threadData?
i am creating a bluetooth based server program in Bluez which basically handles connections from multiple devices. I have constructed two threads; one to scan the remote devices and another to connect with the devices that are broadcasting the service. Again, a separate thread is extracted from a thread pool for each of the newly connected devices which will then communicate with the server over a RFCOMM channel.
After establishing connection with a remote device, the server will send commands to the remote bluetooth device. Once the remote device a reply, the server reads that reply and stores it.
Now, the problem is whenever I get a reply back from the device the program crashes stating a "segmentation fault". Can anyone tell me a possible cause for this. The part of the code that does this is given here.
void startCommunication( int newSocket )
{
char buf[MODZ_MAX_DATA_SIZE] = "\0";
char previousData[ MODZ_MAX_DATA_SIZE ] = "\0";
time_t recvTime, prevRecvTime;
char dataToBeSent[ 4*MODZ_MAX_DATA_SIZE ] = "\0";
char *result;
if( sendDataToClient( newSocket, CMD_SEND) == EXT_ERROR ) //send acknowledgement first
printf("Couldn;t send ack\n");
else { printf("Date send woot! woot! %s\n", CMD_SEND); }
memset( buf, '0', sizeof(buf) );
while( 1 ){
recvTime = time( ( time_t * )0 );
if( readDataFromClient( newSocket, buf ) == EXT_ERROR ){
printf( "Read Error\n" );
break;
}
printf( "Data received = %s\n", buf );
strcpy( previousData, buf );
// store the data in a file and send to web
// check if the web has any data to send and if there is then send
result = "here we update the challenge";
strcpy( dataToBeSent, result );
free( result );
result = NULL;
//strcpy( buf, "We will soon update the database" );
if( sendDataToClient( newSocket, dataToBeSent ) == EXT_ERROR ){
break;
}
}
close( newSocket );
if( result != NULL ){
free( result );
}
printf( "\n****************Device disconnected***************\n" );
}
One obvious problem:
result = "here we update the challenge";
strcpy( dataToBeSent, result );
free( result );
You are freeing a pointer that was not allocated with malloc. That could well cause a segmentation fault.
In the future, try to use gdb to figure out exactly where your program crashes.